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

Annotation of sys/arch/aviion/dev/dart.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: dart.c,v 1.1.1.1 2006/05/09 18:13:32 miod Exp $       */
        !             2:
        !             3: /*
        !             4:  * Mach Operating System
        !             5:  * Copyright (c) 1993-1991 Carnegie Mellon University
        !             6:  * All Rights Reserved.
        !             7:  *
        !             8:  * Permission to use, copy, modify and distribute this software and its
        !             9:  * documentation is hereby granted, provided that both the copyright
        !            10:  * notice and this permission notice appear in all copies of the
        !            11:  * software, derivative works or modified versions, and any portions
        !            12:  * thereof, and that both notices appear in supporting documentation.
        !            13:  *
        !            14:  * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            15:  * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
        !            16:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            17:  *
        !            18:  * Carnegie Mellon requests users of this software to return to
        !            19:  *
        !            20:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            21:  *  School of Computer Science
        !            22:  *  Carnegie Mellon University
        !            23:  *  Pittsburgh PA 15213-3890
        !            24:  *
        !            25:  * any improvements or extensions that they make and grant Carnegie the
        !            26:  * rights to redistribute these changes.
        !            27:  */
        !            28:
        !            29: #include <sys/param.h>
        !            30: #include <sys/ioctl.h>
        !            31: #include <sys/proc.h>
        !            32: #include <sys/tty.h>
        !            33: #include <sys/systm.h>
        !            34: #include <sys/device.h>
        !            35: #include <sys/syslog.h>
        !            36:
        !            37: #include <machine/autoconf.h>
        !            38: #include <machine/conf.h>
        !            39: #include <machine/cpu.h>
        !            40:
        !            41: #include <dev/cons.h>
        !            42:
        !            43: #include <machine/av400.h>
        !            44: #include <aviion/dev/sysconreg.h>
        !            45: #include <aviion/dev/dartreg.h>
        !            46: #include <aviion/dev/dartvar.h>
        !            47:
        !            48: #ifdef DDB
        !            49: #include <ddb/db_var.h>
        !            50: #endif
        !            51:
        !            52: struct cfdriver dart_cd = {
        !            53:        NULL, "dart", DV_TTY
        !            54: };
        !            55:
        !            56: /* console is on the first port */
        !            57: #define        CONS_PORT       A_PORT
        !            58: #ifdef USE_PROM_CONSOLE
        !            59: #define        dartcn_sv       sc->sc_sv_reg_storage
        !            60: #else
        !            61: struct dart_sv_reg dartcn_sv;
        !            62: #endif
        !            63:
        !            64: /* prototypes */
        !            65: cons_decl(dart);
        !            66: int    dart_speed(int);
        !            67: struct tty *darttty(dev_t);
        !            68: void   dartstart(struct tty *);
        !            69: int    dartmctl(struct dartsoftc *, int, int, int);
        !            70: int    dartparam(struct tty *, struct termios *);
        !            71: void   dartmodemtrans(struct dartsoftc *, unsigned int, unsigned int);
        !            72: void   dartrint(struct dartsoftc *, int);
        !            73: void   dartxint(struct dartsoftc *, int);
        !            74:
        !            75: /*
        !            76:  * DUART registers are mapped as the least-significant byte of 32-bit
        !            77:  * addresses. The following macros hide this.
        !            78:  */
        !            79:
        !            80: #define        dart_read(sc, reg) \
        !            81:        bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, 3 + ((reg) << 2))
        !            82: #define        dart_write(sc, reg, val) \
        !            83:        bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, 3 + ((reg) << 2), (val))
        !            84:
        !            85: #define        DART_CHIP(dev)  (minor(dev) >> 1)
        !            86: #define DART_PORT(dev) (minor(dev) & 1)
        !            87:
        !            88: void
        !            89: dart_common_attach(struct dartsoftc *sc)
        !            90: {
        !            91:        if (sc->sc_console) {
        !            92:                sc->sc_sv_reg = &dartcn_sv;
        !            93:
        !            94:                if (A_PORT != CONS_PORT) {
        !            95:                        sc->sc_sv_reg->sv_mr1[A_PORT] = PARDIS | RXRTS | CL8;
        !            96:                        sc->sc_sv_reg->sv_mr2[A_PORT] = /* TXCTS | */ SB1;
        !            97:                        sc->sc_sv_reg->sv_csr[A_PORT] = BD9600;
        !            98:                        sc->sc_sv_reg->sv_cr[A_PORT]  = TXEN | RXEN;
        !            99:                        sc->sc_sv_reg->sv_opr |= OPDTRA | OPRTSA;
        !           100:                } else {
        !           101:                        sc->sc_sv_reg->sv_mr1[B_PORT] = PARDIS | RXRTS | CL8;
        !           102:                        sc->sc_sv_reg->sv_mr2[B_PORT] = /* TXCTS | */ SB1;
        !           103:                        sc->sc_sv_reg->sv_csr[B_PORT] = BD9600;
        !           104:                        sc->sc_sv_reg->sv_cr[B_PORT]  = TXEN | RXEN;
        !           105:                        sc->sc_sv_reg->sv_opr |= OPDTRB | OPRTSB;
        !           106:                }
        !           107:        } else {
        !           108:                sc->sc_sv_reg = &sc->sc_sv_reg_storage;
        !           109:
        !           110:                sc->sc_sv_reg->sv_mr1[A_PORT] = PARDIS | RXRTS | CL8;
        !           111:                sc->sc_sv_reg->sv_mr2[A_PORT] = /* TXCTS | */ SB1;
        !           112:                sc->sc_sv_reg->sv_csr[A_PORT] = BD9600;
        !           113:                sc->sc_sv_reg->sv_cr[A_PORT]  = TXEN | RXEN;
        !           114:
        !           115:                sc->sc_sv_reg->sv_mr1[B_PORT] = PARDIS | RXRTS | CL8;
        !           116:                sc->sc_sv_reg->sv_mr2[B_PORT] = /* TXCTS | */ SB1;
        !           117:                sc->sc_sv_reg->sv_csr[B_PORT] = BD9600;
        !           118:                sc->sc_sv_reg->sv_cr[B_PORT]  = TXEN | RXEN;
        !           119:
        !           120:                sc->sc_sv_reg->sv_opr = OPDTRA | OPRTSA | OPDTRB | OPRTSB;
        !           121:
        !           122:                /* Start out with Tx and RX interrupts disabled */
        !           123:                /* Enable input port change interrupt */
        !           124:                sc->sc_sv_reg->sv_imr  = IIPCHG;
        !           125:        }
        !           126:
        !           127:        /* reset port a */
        !           128:        if (sc->sc_console == 0 || CONS_PORT != A_PORT) {
        !           129:                dart_write(sc, DART_CRA, RXRESET | TXDIS | RXDIS);
        !           130:                DELAY_CR;
        !           131:                dart_write(sc, DART_CRA, TXRESET | TXDIS | RXDIS);
        !           132:                DELAY_CR;
        !           133:                dart_write(sc, DART_CRA, ERRRESET | TXDIS | RXDIS);
        !           134:                DELAY_CR;
        !           135:                dart_write(sc, DART_CRA, BRKINTRESET | TXDIS | RXDIS);
        !           136:                DELAY_CR;
        !           137:                dart_write(sc, DART_CRA, MRRESET | TXDIS | RXDIS);
        !           138: #if 0
        !           139:                DELAY_CR;
        !           140: #endif
        !           141:
        !           142:                dart_write(sc, DART_MR1A, sc->sc_sv_reg->sv_mr1[A_PORT]);
        !           143:                dart_write(sc, DART_MR2A, sc->sc_sv_reg->sv_mr2[A_PORT]);
        !           144:                dart_write(sc, DART_CSRA, sc->sc_sv_reg->sv_csr[A_PORT]);
        !           145:                dart_write(sc, DART_CRA, sc->sc_sv_reg->sv_cr[A_PORT]);
        !           146:        }
        !           147:
        !           148:        /* reset port b */
        !           149:        if (sc->sc_console == 0 || CONS_PORT != B_PORT) {
        !           150:                dart_write(sc, DART_CRB, RXRESET | TXDIS | RXDIS);
        !           151:                DELAY_CR;
        !           152:                dart_write(sc, DART_CRB, TXRESET | TXDIS | RXDIS);
        !           153:                DELAY_CR;
        !           154:                dart_write(sc, DART_CRB, ERRRESET | TXDIS | RXDIS);
        !           155:                DELAY_CR;
        !           156:                dart_write(sc, DART_CRB, BRKINTRESET | TXDIS | RXDIS);
        !           157:                DELAY_CR;
        !           158:                dart_write(sc, DART_CRB, MRRESET | TXDIS | RXDIS);
        !           159: #if 0
        !           160:                DELAY_CR;
        !           161: #endif
        !           162:
        !           163:                dart_write(sc, DART_MR1B, sc->sc_sv_reg->sv_mr1[B_PORT]);
        !           164:                dart_write(sc, DART_MR2B, sc->sc_sv_reg->sv_mr2[B_PORT]);
        !           165:                dart_write(sc, DART_CSRB, sc->sc_sv_reg->sv_csr[B_PORT]);
        !           166:                dart_write(sc, DART_CRB, sc->sc_sv_reg->sv_cr[B_PORT]);
        !           167:        }
        !           168:
        !           169:        /* initialize common register of a DUART */
        !           170:        dart_write(sc, DART_OPRS, sc->sc_sv_reg->sv_opr);
        !           171:
        !           172: #if 0
        !           173:        dart_write(sc, DART_CTUR, SLCTIM >> 8);
        !           174:        dart_write(sc, DART_CTLR, SLCTIM & 0xff);
        !           175:        dart_write(sc, DART_ACR, BDSET2 | CCLK16 | IPDCDIB | IPDCDIA);
        !           176: #endif
        !           177:        dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
        !           178: #if 0
        !           179:        dart_write(sc, DART_OPCR, OPSET);
        !           180: #endif
        !           181: #if 0
        !           182:        dart_write(sc, DART_IVR, SYSCON_VECT + SYSCV_SCC);
        !           183: #endif
        !           184:
        !           185:        sc->sc_dart[A_PORT].tty = sc->sc_dart[B_PORT].tty = NULL;
        !           186:        sc->sc_dart[A_PORT].dart_swflags = sc->sc_dart[B_PORT].dart_swflags = 0;
        !           187:        if (sc->sc_console)
        !           188:                sc->sc_dart[CONS_PORT].dart_swflags |= TIOCFLAG_SOFTCAR;
        !           189:
        !           190:        printf("\n");
        !           191: }
        !           192:
        !           193: /* speed tables */
        !           194: const struct dart_s {
        !           195:        int kspeed;
        !           196:        int dspeed;
        !           197: } dart_speeds[] = {
        !           198:        { B0,           0       },      /* 0 baud, special HUP condition */
        !           199:         { B50,         NOBAUD  },      /* 50 baud, not implemented */
        !           200:        { B75,          BD75    },      /* 75 baud */
        !           201:        { B110,         BD110   },      /* 110 baud */
        !           202:        { B134,         BD134   },      /* 134.5 baud */
        !           203:        { B150,         BD150   },      /* 150 baud */
        !           204:        { B200,         NOBAUD  },      /* 200 baud, not implemented */
        !           205:        { B300,         BD300   },      /* 300 baud */
        !           206:        { B600,         BD600   },      /* 600 baud */
        !           207:        { B1200,        BD1200  },      /* 1200 baud */
        !           208:        { B1800,        BD1800  },      /* 1800 baud */
        !           209:        { B2400,        BD2400  },      /* 2400 baud */
        !           210:        { B4800,        BD4800  },      /* 4800 baud */
        !           211:        { B9600,        BD9600  },      /* 9600 baud */
        !           212:        { B19200,       BD19200 },      /* 19200 baud */
        !           213:        { -1,           NOBAUD  },      /* anything more is uncivilized */
        !           214: };
        !           215:
        !           216: int
        !           217: dart_speed(int speed)
        !           218: {
        !           219:        const struct dart_s *ds;
        !           220:
        !           221:        for (ds = dart_speeds; ds->kspeed != -1; ds++)
        !           222:                if (ds->kspeed == speed)
        !           223:                        return ds->dspeed;
        !           224:
        !           225:        return NOBAUD;
        !           226: }
        !           227:
        !           228: struct tty *
        !           229: darttty(dev_t dev)
        !           230: {
        !           231:        u_int port, chip;
        !           232:        struct dartsoftc *sc;
        !           233:
        !           234:        chip = DART_CHIP(dev);
        !           235:        port = DART_PORT(dev);
        !           236:        if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS)
        !           237:                return (NULL);
        !           238:
        !           239:        sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
        !           240:        if (sc == NULL)
        !           241:                return (NULL);
        !           242:
        !           243:        return sc->sc_dart[port].tty;
        !           244: }
        !           245:
        !           246: void
        !           247: dartstart(struct tty *tp)
        !           248: {
        !           249:        struct dartsoftc *sc;
        !           250:        dev_t dev;
        !           251:        int s;
        !           252:        u_int port, chip;
        !           253:        int c, tries;
        !           254:        bus_addr_t ptaddr;
        !           255:
        !           256:        if ((tp->t_state & TS_ISOPEN) == 0)
        !           257:                return;
        !           258:
        !           259:        dev = tp->t_dev;
        !           260:        chip = DART_CHIP(dev);
        !           261:        port = DART_PORT(dev);
        !           262:        sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
        !           263:        ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
        !           264:
        !           265:        s = spltty();
        !           266:
        !           267:        if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
        !           268:                goto bail;
        !           269:
        !           270:        if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           271:                if (tp->t_state & TS_ASLEEP) {
        !           272:                        tp->t_state &= ~TS_ASLEEP;
        !           273:                        wakeup((caddr_t)&tp->t_outq);
        !           274:                }
        !           275:                selwakeup(&tp->t_wsel);
        !           276:                if (tp->t_outq.c_cc == 0)
        !           277:                        goto bail;
        !           278:        }
        !           279:
        !           280:        tp->t_state |= TS_BUSY;
        !           281:        while (tp->t_outq.c_cc != 0) {
        !           282:
        !           283:                /* load transmitter until it is full */
        !           284:                for (tries = 10000; tries != 0; tries --)
        !           285:                        if (dart_read(sc, ptaddr + DART_SRA) & TXRDY)
        !           286:                                break;
        !           287:
        !           288:                if (tries == 0) {
        !           289:                        timeout_add(&tp->t_rstrt_to, 1);
        !           290:                        tp->t_state |= TS_TIMEOUT;
        !           291:                        break;
        !           292:                } else {
        !           293:                        c = getc(&tp->t_outq);
        !           294:
        !           295:                        dart_write(sc, ptaddr + DART_TBA, c & 0xff);
        !           296:
        !           297:                        sc->sc_sv_reg->sv_imr |=
        !           298:                            port == A_PORT ? ITXRDYA : ITXRDYB;
        !           299:                        dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
        !           300:                }
        !           301:        }
        !           302:        tp->t_state &= ~TS_BUSY;
        !           303:
        !           304: bail:
        !           305:        splx(s);
        !           306: }
        !           307:
        !           308: int
        !           309: dartstop(struct tty *tp, int flag)
        !           310: {
        !           311:        int s;
        !           312:
        !           313:        s = spltty();
        !           314:        if (tp->t_state & TS_BUSY) {
        !           315:                if ((tp->t_state & TS_TTSTOP) == 0)
        !           316:                        tp->t_state |= TS_FLUSH;
        !           317:        }
        !           318:        splx(s);
        !           319:
        !           320:        return 0;
        !           321: }
        !           322:
        !           323: /*
        !           324:  * To be called at spltty - tty already locked.
        !           325:  * Returns status of carrier.
        !           326:  */
        !           327: int
        !           328: dartmctl(struct dartsoftc *sc, int port, int flags, int how)
        !           329: {
        !           330:        int newflags, flagsmask;
        !           331:        struct dart_info *dart;
        !           332:        int s;
        !           333:
        !           334:        dart = &sc->sc_dart[port];
        !           335:
        !           336:        s = spltty();
        !           337:
        !           338:        flagsmask = port == A_PORT ? (OPDTRA | OPRTSA) : (OPDTRB | OPRTSB);
        !           339:        newflags = (flags & TIOCM_DTR ? (OPDTRA | OPDTRB) : 0) |
        !           340:            (flags & TIOCM_RTS ? (OPRTSA | OPRTSB) : 0);
        !           341:        newflags &= flagsmask;  /* restrict to the port we are acting on */
        !           342:
        !           343:        switch (how) {
        !           344:        case DMSET:
        !           345:                dart_write(sc, DART_OPRS, newflags);
        !           346:                dart_write(sc, DART_OPRR, ~newflags);
        !           347:                /* only replace the sv_opr bits for the port we are acting on */
        !           348:                sc->sc_sv_reg->sv_opr &= ~flagsmask;
        !           349:                sc->sc_sv_reg->sv_opr |= newflags;
        !           350:                break;
        !           351:        case DMBIS:
        !           352:                dart_write(sc, DART_OPRS, newflags);
        !           353:                sc->sc_sv_reg->sv_opr |= newflags;
        !           354:                break;
        !           355:        case DMBIC:
        !           356:                dart_write(sc, DART_OPRR, newflags);
        !           357:                sc->sc_sv_reg->sv_opr &= ~newflags;
        !           358:                break;
        !           359:        case DMGET:
        !           360:                flags = 0;
        !           361:                if (port == A_PORT) {
        !           362:                        if (sc->sc_sv_reg->sv_opr & OPDTRA)
        !           363:                                flags |= TIOCM_DTR;
        !           364:                        if (sc->sc_sv_reg->sv_opr & OPRTSA)
        !           365:                                flags |= TIOCM_RTS;
        !           366:                } else {
        !           367:                        if (sc->sc_sv_reg->sv_opr & OPDTRB)
        !           368:                                flags |= TIOCM_DTR;
        !           369:                        if (sc->sc_sv_reg->sv_opr & OPRTSB)
        !           370:                                flags |= TIOCM_RTS;
        !           371:                }
        !           372:                break;
        !           373:        }
        !           374:
        !           375:        splx(s);
        !           376:        return (flags);
        !           377: }
        !           378:
        !           379: int
        !           380: dartioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
        !           381: {
        !           382:        int error;
        !           383:        u_int port, chip;
        !           384:        struct tty *tp;
        !           385:        struct dart_info *dart;
        !           386:        struct dartsoftc *sc;
        !           387:
        !           388:        chip = DART_CHIP(dev);
        !           389:        port = DART_PORT(dev);
        !           390:        sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
        !           391:        dart = &sc->sc_dart[port];
        !           392:
        !           393:        tp = dart->tty;
        !           394:        if (tp == NULL)
        !           395:                return (ENXIO);
        !           396:
        !           397:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
        !           398:        if (error >= 0)
        !           399:                return(error);
        !           400:
        !           401:        error = ttioctl(tp, cmd, data, flag, p);
        !           402:        if (error >= 0)
        !           403:                return(error);
        !           404:
        !           405:        switch (cmd) {
        !           406:        case TIOCSBRK:
        !           407:        case TIOCCBRK:
        !           408:                break;
        !           409:        case TIOCSDTR:
        !           410:                (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIS);
        !           411:                break;
        !           412:        case TIOCCDTR:
        !           413:                (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIC);
        !           414:                break;
        !           415:        case TIOCMSET:
        !           416:                (void)dartmctl(sc, port, *(int *) data, DMSET);
        !           417:                break;
        !           418:        case TIOCMBIS:
        !           419:                (void)dartmctl(sc, port, *(int *) data, DMBIS);
        !           420:                break;
        !           421:        case TIOCMBIC:
        !           422:                (void)dartmctl(sc, port, *(int *) data, DMBIC);
        !           423:                break;
        !           424:        case TIOCMGET:
        !           425:                *(int *)data = dartmctl(sc, port, 0, DMGET);
        !           426:                break;
        !           427:        case TIOCGFLAGS:
        !           428:                *(int *)data = dart->dart_swflags;
        !           429:                break;
        !           430:        case TIOCSFLAGS:
        !           431:                error = suser(p, 0);
        !           432:                if (error != 0)
        !           433:                        return (EPERM);
        !           434:
        !           435:                dart->dart_swflags = *(int *)data;
        !           436:                dart->dart_swflags &= /* only allow valid flags */
        !           437:                        (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
        !           438:                break;
        !           439:        default:
        !           440:                return (ENOTTY);
        !           441:        }
        !           442:
        !           443:        return (0);
        !           444: }
        !           445:
        !           446: int
        !           447: dartparam(struct tty *tp, struct termios *t)
        !           448: {
        !           449:        int flags;
        !           450:        u_int port, chip;
        !           451:        int speeds;
        !           452:        unsigned char mr1, mr2;
        !           453:        struct dart_info *dart;
        !           454:        struct dartsoftc *sc;
        !           455:        dev_t dev;
        !           456:        bus_addr_t ptaddr;
        !           457:
        !           458:        dev = tp->t_dev;
        !           459:        chip = DART_CHIP(dev);
        !           460:        port = DART_PORT(dev);
        !           461:        sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
        !           462:        dart = &sc->sc_dart[port];
        !           463:        ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
        !           464:
        !           465:        tp->t_ispeed = t->c_ispeed;
        !           466:        tp->t_ospeed = t->c_ospeed;
        !           467:        tp->t_cflag = t->c_cflag;
        !           468:
        !           469:        flags = tp->t_flags;
        !           470:
        !           471:        /* Reset to make global changes*/
        !           472:        /* disable Tx and Rx */
        !           473:
        !           474:        if (sc->sc_console == 0 || CONS_PORT != port) {
        !           475:                if (port == A_PORT)
        !           476:                        sc->sc_sv_reg->sv_imr &= ~(ITXRDYA | IRXRDYA);
        !           477:                else
        !           478:                        sc->sc_sv_reg->sv_imr &= ~(ITXRDYB | IRXRDYB);
        !           479:                dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
        !           480:
        !           481:                /* hang up on zero baud rate */
        !           482:                if (tp->t_ispeed == 0) {
        !           483:                        dartmctl(sc, port, HUPCL, DMSET);
        !           484:                        return (0);
        !           485:                } else {
        !           486:                        /* set baudrate */
        !           487:                        speeds = dart_speed(tp->t_ispeed);
        !           488:                        if (speeds == NOBAUD)
        !           489:                                speeds = sc->sc_sv_reg->sv_csr[port];
        !           490:                        dart_write(sc, ptaddr + DART_CSRA, speeds);
        !           491:                        sc->sc_sv_reg->sv_csr[port] = speeds;
        !           492:                }
        !           493:
        !           494:                /* get saved mode registers and clear set up parameters */
        !           495:                mr1 = sc->sc_sv_reg->sv_mr1[port];
        !           496:                mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK);
        !           497:
        !           498:                mr2 = sc->sc_sv_reg->sv_mr2[port];
        !           499:                mr2 &= ~SBMASK;
        !           500:
        !           501:                /* set up character size */
        !           502:                switch (t->c_cflag & CSIZE) {
        !           503:                case CL8:
        !           504:                        mr1 |= CL8;
        !           505:                        break;
        !           506:                case CL7:
        !           507:                        mr1 |= CL7;
        !           508:                        break;
        !           509:                case CL6:
        !           510:                        mr1 |= CL6;
        !           511:                        break;
        !           512:                case CL5:
        !           513:                        mr1 |= CL5;
        !           514:                        break;
        !           515:                }
        !           516:
        !           517:                /* set up stop bits */
        !           518:                if (tp->t_ospeed == B110)
        !           519:                        mr2 |= SB2;
        !           520:                else
        !           521:                        mr2 |= SB1;
        !           522:
        !           523:                /* set up parity */
        !           524:                if (t->c_cflag & PARENB) {
        !           525:                        mr1 |= PAREN;
        !           526:                        if (t->c_cflag & PARODD)
        !           527:                                mr1 |= ODDPAR;
        !           528:                        else
        !           529:                                mr1 |= EVENPAR;
        !           530:                } else
        !           531:                        mr1 |= PARDIS;
        !           532:
        !           533:                if (sc->sc_sv_reg->sv_mr1[port] != mr1 ||
        !           534:                    sc->sc_sv_reg->sv_mr2[port] != mr2) {
        !           535:                        /* write mode registers to duart */
        !           536:                        dart_write(sc, ptaddr + DART_CRA, MRRESET);
        !           537:                        dart_write(sc, ptaddr + DART_MR1A, mr1);
        !           538:                        dart_write(sc, ptaddr + DART_MR2A, mr2);
        !           539:
        !           540:                        /* save changed mode registers */
        !           541:                        sc->sc_sv_reg->sv_mr1[port] = mr1;
        !           542:                        sc->sc_sv_reg->sv_mr2[port] = mr2;
        !           543:                }
        !           544:        }
        !           545:
        !           546:        /* enable transmitter? */
        !           547:        if (tp->t_state & TS_BUSY) {
        !           548:                sc->sc_sv_reg->sv_imr |= port == A_PORT ? ITXRDYA : ITXRDYB;
        !           549:                dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
        !           550:        }
        !           551:
        !           552:        /* re-enable the receiver */
        !           553: #if 0
        !           554:        DELAY_CR;
        !           555: #endif
        !           556:        sc->sc_sv_reg->sv_imr |= port == A_PORT ? IRXRDYA : IRXRDYB;
        !           557:        dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
        !           558:
        !           559:        return (0);
        !           560: }
        !           561:
        !           562: void
        !           563: dartmodemtrans(struct dartsoftc *sc, unsigned int ip, unsigned int ipcr)
        !           564: {
        !           565:        unsigned int dcdstate;
        !           566:        struct tty *tp;
        !           567:        int port;
        !           568:        struct dart_info *dart;
        !           569:
        !           570:        /* input is inverted at port!!! */
        !           571:        if (ipcr & IPCRDCDA) {
        !           572:                port = A_PORT;
        !           573:                dcdstate = !(ip & IPDCDA);
        !           574:        } else if (ipcr & IPCRDCDB) {
        !           575:                port = B_PORT;
        !           576:                dcdstate = !(ip & IPDCDB);
        !           577:        } else {
        !           578: #ifdef DIAGNOSTIC
        !           579:                printf("dartmodemtrans: unknown transition ip=0x%x ipcr=0x%x\n",
        !           580:                       ip, ipcr);
        !           581: #endif
        !           582:                return;
        !           583:        }
        !           584:
        !           585:        dart = &sc->sc_dart[port];
        !           586:        tp = dart->tty;
        !           587:        if (tp != NULL)
        !           588:                ttymodem(tp, dcdstate);
        !           589: }
        !           590:
        !           591: int
        !           592: dartopen(dev_t dev, int flag, int mode, struct proc *p)
        !           593: {
        !           594:        int s;
        !           595:        u_int port, chip;
        !           596:        struct dart_info *dart;
        !           597:        struct dartsoftc *sc;
        !           598:        struct tty *tp;
        !           599:
        !           600:        chip = DART_CHIP(dev);
        !           601:        port = DART_PORT(dev);
        !           602:        if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS)
        !           603:                return (ENODEV);
        !           604:        sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
        !           605:        if (sc == NULL)
        !           606:                return (ENODEV);
        !           607:        dart = &sc->sc_dart[port];
        !           608:
        !           609:        s = spltty();
        !           610:        if (dart->tty != NULL)
        !           611:                tp = dart->tty;
        !           612:        else
        !           613:                tp = dart->tty = ttymalloc();
        !           614:
        !           615:        tp->t_oproc = dartstart;
        !           616:        tp->t_param = dartparam;
        !           617:        tp->t_dev = dev;
        !           618:
        !           619:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           620:                ttychars(tp);
        !           621:
        !           622:                if (tp->t_ispeed == 0) {
        !           623:                        tp->t_iflag = TTYDEF_IFLAG;
        !           624:                        tp->t_oflag = TTYDEF_OFLAG;
        !           625:                        tp->t_lflag = TTYDEF_LFLAG;
        !           626:                        tp->t_ispeed = tp->t_ospeed = B9600;
        !           627:                        if (sc->sc_console && port == CONS_PORT) {
        !           628:                                /* console is 8N1 */
        !           629:                                tp->t_cflag = (CREAD | CS8 | HUPCL);
        !           630:                        } else {
        !           631:                                tp->t_cflag = TTYDEF_CFLAG;
        !           632:                        }
        !           633:                }
        !           634:
        !           635:                if (dart->dart_swflags & TIOCFLAG_CLOCAL)
        !           636:                        tp->t_cflag |= CLOCAL;
        !           637:                if (dart->dart_swflags & TIOCFLAG_CRTSCTS)
        !           638:                        tp->t_cflag |= CRTSCTS;
        !           639:                if (dart->dart_swflags & TIOCFLAG_MDMBUF)
        !           640:                        tp->t_cflag |= MDMBUF;
        !           641:
        !           642:                dartparam(tp, &tp->t_termios);
        !           643:                ttsetwater(tp);
        !           644:
        !           645:                (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMSET);
        !           646:                tp->t_state |= TS_CARR_ON;
        !           647:        } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
        !           648:                splx(s);
        !           649:                return (EBUSY);
        !           650:        }
        !           651:
        !           652:        /*
        !           653:         * Reset the tty pointer, as there could have been a dialout
        !           654:         * use of the tty with a dialin open waiting.
        !           655:         */
        !           656:        tp->t_dev = dev;
        !           657:        splx(s);
        !           658:        return ((*linesw[tp->t_line].l_open)(dev, tp));
        !           659: }
        !           660:
        !           661: int
        !           662: dartclose(dev_t dev, int flag, int mode, struct proc *p)
        !           663: {
        !           664:        struct tty *tp;
        !           665:        struct dart_info *dart;
        !           666:        struct dartsoftc *sc;
        !           667:        u_int port, chip;
        !           668:
        !           669:        chip = DART_CHIP(dev);
        !           670:        port = DART_PORT(dev);
        !           671:        sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
        !           672:        dart = &sc->sc_dart[port];
        !           673:
        !           674:        tp = dart->tty;
        !           675:        (*linesw[tp->t_line].l_close)(tp, flag);
        !           676:        ttyclose(tp);
        !           677:
        !           678:        return (0);
        !           679: }
        !           680:
        !           681: int
        !           682: dartread(dev_t dev, struct uio *uio, int flag)
        !           683: {
        !           684:        u_int port, chip;
        !           685:        struct tty *tp;
        !           686:        struct dart_info *dart;
        !           687:        struct dartsoftc *sc;
        !           688:
        !           689:        chip = DART_CHIP(dev);
        !           690:        port = DART_PORT(dev);
        !           691:        sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
        !           692:        dart = &sc->sc_dart[port];
        !           693:
        !           694:        tp = dart->tty;
        !           695:        if (tp == NULL)
        !           696:                return (ENXIO);
        !           697:        return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
        !           698: }
        !           699:
        !           700: int
        !           701: dartwrite(dev_t dev, struct uio *uio, int flag)
        !           702: {
        !           703:        u_int port, chip;
        !           704:        struct tty *tp;
        !           705:        struct dart_info *dart;
        !           706:        struct dartsoftc *sc;
        !           707:
        !           708:        chip = DART_CHIP(dev);
        !           709:        port = DART_PORT(dev);
        !           710:        sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
        !           711:        dart = &sc->sc_dart[port];
        !           712:
        !           713:        tp = dart->tty;
        !           714:        if (tp == NULL)
        !           715:                return (ENXIO);
        !           716:        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
        !           717: }
        !           718:
        !           719: void
        !           720: dartrint(struct dartsoftc *sc, int port)
        !           721: {
        !           722:        struct tty *tp;
        !           723:        unsigned char data, sr;
        !           724:        struct dart_info *dart;
        !           725:        bus_addr_t ptaddr;
        !           726:
        !           727:        dart = &sc->sc_dart[port];
        !           728:        ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
        !           729:        tp = dart->tty;
        !           730:
        !           731:        /* read status reg */
        !           732:        while ((sr = dart_read(sc, ptaddr + DART_SRA)) & RXRDY) {
        !           733:                /* read data and reset receiver */
        !           734:                data = dart_read(sc, ptaddr + DART_RBA);
        !           735:
        !           736:                if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0 &&
        !           737:                    (sc->sc_console == 0 || CONS_PORT != port)) {
        !           738:                        return;
        !           739:                }
        !           740:
        !           741:                if (sr & RBRK) {
        !           742:                        /* clear break state */
        !           743:                        dart_write(sc, ptaddr + DART_CRA, BRKINTRESET);
        !           744:                        DELAY_CR;
        !           745:                        dart_write(sc, ptaddr + DART_CRA, ERRRESET);
        !           746:
        !           747: #if defined(DDB)
        !           748:                        if (db_console != 0 &&
        !           749:                            sc->sc_console && port == CONS_PORT)
        !           750:                                Debugger();
        !           751: #endif
        !           752:                } else {
        !           753:                        if (sr & (FRERR | PERR | ROVRN)) { /* errors */
        !           754:                                if (sr & ROVRN)
        !           755:                                        log(LOG_WARNING, "%s port %c: "
        !           756:                                            "receiver overrun\n",
        !           757:                                            sc->sc_dev.dv_xname, 'A' + port);
        !           758:                                if (sr & FRERR)
        !           759:                                        log(LOG_WARNING, "%s port %c: "
        !           760:                                            "framing error\n",
        !           761:                                            sc->sc_dev.dv_xname, 'A' + port);
        !           762:                                if (sr & PERR)
        !           763:                                        log(LOG_WARNING, "%s port %c: "
        !           764:                                            "parity error\n",
        !           765:                                            sc->sc_dev.dv_xname, 'A' + port);
        !           766:                                /* clear error state */
        !           767:                                dart_write(sc, ptaddr + DART_CRA, ERRRESET);
        !           768:                        } else {
        !           769:                                /* no errors */
        !           770:                                (*linesw[tp->t_line].l_rint)(data,tp);
        !           771:                        }
        !           772:                }
        !           773:        }
        !           774: }
        !           775:
        !           776: void
        !           777: dartxint(struct dartsoftc *sc, int port)
        !           778: {
        !           779:        struct tty *tp;
        !           780:        struct dart_info *dart;
        !           781:
        !           782:        dart = &sc->sc_dart[port];
        !           783:        tp = dart->tty;
        !           784:
        !           785:        if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0)
        !           786:                goto out;
        !           787:
        !           788:        if (tp->t_state & TS_BUSY) {
        !           789:                tp->t_state &= ~(TS_BUSY | TS_FLUSH);
        !           790:                dartstart(tp);
        !           791:                if (tp->t_state & TS_BUSY) {
        !           792:                        /* do not disable transmitter, yet */
        !           793:                        return;
        !           794:                }
        !           795:        }
        !           796: out:
        !           797:
        !           798:        /* disable transmitter */
        !           799:        sc->sc_sv_reg->sv_imr &= port == A_PORT ? ~ITXRDYA : ~ITXRDYB;
        !           800:        dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
        !           801: }
        !           802:
        !           803: int
        !           804: dartintr(void *arg)
        !           805: {
        !           806:        struct dartsoftc *sc = arg;
        !           807:        unsigned char isr, imr;
        !           808:        int port;
        !           809:
        !           810:        /* read interrupt status register and mask with imr */
        !           811:        isr = dart_read(sc, DART_ISR);
        !           812:        imr = sc->sc_sv_reg->sv_imr;
        !           813:
        !           814:        if ((isr & imr) == 0) {
        !           815:                /*
        !           816:                 * We got an interrupt on a disabled condition (such as TX
        !           817:                 * ready change on a disabled port). This should not happen,
        !           818:                 * but we have to claim the interrupt anyway.
        !           819:                 */
        !           820: #ifdef DIAGNOSTIC
        !           821:                printf("%s: spurious interrupt, isr %x imr %x\n",
        !           822:                    sc->sc_dev.dv_xname, isr, imr);
        !           823: #endif
        !           824:                return (1);
        !           825:        }
        !           826:        isr &= imr;
        !           827:
        !           828:        if (isr & IIPCHG) {
        !           829:                unsigned int ip, ipcr;
        !           830:
        !           831:                ip = dart_read(sc, DART_IP);
        !           832:                ipcr = dart_read(sc, DART_IPCR);
        !           833:                dartmodemtrans(sc, ip, ipcr);
        !           834:                return (1);
        !           835:        }
        !           836:
        !           837:        if (isr & (IRXRDYA | ITXRDYA))
        !           838:                port = 0;
        !           839: #ifdef DIAGNOSTIC
        !           840:        else if ((isr & (IRXRDYB | ITXRDYB)) == 0) {
        !           841:                printf("%s: spurious interrupt, isr %x\n",
        !           842:                    sc->sc_dev.dv_xname, isr);
        !           843:                return (1);     /* claim it anyway */
        !           844:        }
        !           845: #endif
        !           846:        else
        !           847:                port = 1;
        !           848:
        !           849:        if (isr & (IRXRDYA | IRXRDYB))
        !           850:                dartrint(sc, port);
        !           851:        if (isr & (ITXRDYA | ITXRDYB))
        !           852:                dartxint(sc, port);
        !           853:        if (isr & (port == A_PORT ? IBRKA : IBRKB))
        !           854:                dart_write(sc, port == A_PORT ? DART_CRA : DART_CRB,
        !           855:                    BRKINTRESET);
        !           856:
        !           857:        return (1);
        !           858: }
        !           859:
        !           860: /*
        !           861:  * Console interface routines.
        !           862: #ifdef USE_PROM_CONSOLE
        !           863:  * Since we select the actual console after all devices are attached,
        !           864:  * we can safely pick the appropriate softc and use its information.
        !           865: #endif
        !           866:  */
        !           867:
        !           868: #ifdef USE_PROM_CONSOLE
        !           869: #define        dart_cnread(reg)        dart_read(sc, (reg))
        !           870: #define        dart_cnwrite(reg, val)  dart_write(sc, (reg), (val))
        !           871: #else
        !           872: #define        dart_cnread(reg) \
        !           873:        *(volatile u_int8_t *)(DART_BASE + 3 + ((reg) << 2))
        !           874: #define        dart_cnwrite(reg, val) \
        !           875:        *(volatile u_int8_t *)(DART_BASE + 3 + ((reg) << 2)) = (val)
        !           876: #endif
        !           877:
        !           878: void
        !           879: dartcnprobe(struct consdev *cp)
        !           880: {
        !           881:        int maj;
        !           882:
        !           883:        if (badaddr(DART_BASE, 4) != 0)
        !           884:                return;
        !           885:
        !           886: #ifdef USE_PROM_CONSOLE
        !           887:        /* do not attach as console if dart has been disabled */
        !           888:        if (dart_cd.cd_ndevs == 0 || dart_cd.cd_devs[0] == NULL)
        !           889:                return;
        !           890: #endif
        !           891:
        !           892:        /* locate the major number */
        !           893:        for (maj = 0; maj < nchrdev; maj++)
        !           894:                if (cdevsw[maj].d_open == dartopen)
        !           895:                        break;
        !           896:        if (maj == nchrdev)
        !           897:                return;
        !           898:
        !           899:        cp->cn_dev = makedev(maj, CONS_PORT);
        !           900:        cp->cn_pri = CN_NORMAL;
        !           901: }
        !           902:
        !           903: void
        !           904: dartcninit(cp)
        !           905:        struct consdev *cp;
        !           906: {
        !           907: #ifndef USE_PROM_CONSOLE
        !           908:        dartcn_sv.sv_mr1[CONS_PORT] = PARDIS | RXRTS | CL8;
        !           909:        dartcn_sv.sv_mr2[CONS_PORT] = /* TXCTS | */ SB1;
        !           910:        dartcn_sv.sv_csr[CONS_PORT] = BD9600;
        !           911:        dartcn_sv.sv_cr[CONS_PORT]  = TXEN | RXEN;
        !           912:        dartcn_sv.sv_opr = CONS_PORT == A_PORT ? (OPDTRA | OPRTSA) :
        !           913:             (OPDTRB | OPRTSB);
        !           914:        dartcn_sv.sv_imr = IIPCHG;
        !           915:
        !           916:        dart_cnwrite(DART_CRA, RXRESET | TXDIS | RXDIS);
        !           917:        DELAY_CR;
        !           918:        dart_cnwrite(DART_CRA, TXRESET | TXDIS | RXDIS);
        !           919:        DELAY_CR;
        !           920:        dart_cnwrite(DART_CRA, ERRRESET | TXDIS | RXDIS);
        !           921:        DELAY_CR;
        !           922:        dart_cnwrite(DART_CRA, BRKINTRESET | TXDIS | RXDIS);
        !           923:        DELAY_CR;
        !           924:        dart_cnwrite(DART_CRA, MRRESET | TXDIS | RXDIS);
        !           925:        DELAY_CR;
        !           926:
        !           927:        dart_cnwrite(DART_MR1A, dartcn_sv.sv_mr1[CONS_PORT]);
        !           928:        dart_cnwrite(DART_MR2A, dartcn_sv.sv_mr2[CONS_PORT]);
        !           929:        dart_cnwrite(DART_CSRA, dartcn_sv.sv_csr[CONS_PORT]);
        !           930:        dart_cnwrite(DART_CRA, dartcn_sv.sv_cr[CONS_PORT]);
        !           931:
        !           932:        dart_cnwrite(DART_OPRS, dartcn_sv.sv_opr);
        !           933:
        !           934:        dart_cnwrite(DART_IMR, dartcn_sv.sv_imr);
        !           935: #endif
        !           936: }
        !           937:
        !           938: void
        !           939: dartcnputc(dev_t dev, int c)
        !           940: {
        !           941: #ifdef USE_PROM_CONSOLE
        !           942:        struct dartsoftc *sc;
        !           943: #endif
        !           944:        int s;
        !           945:        u_int port;
        !           946:        bus_addr_t ptaddr;
        !           947:
        !           948: #ifdef USE_PROM_CONSOLE
        !           949:        sc = (struct dartsoftc *)dart_cd.cd_devs[0];
        !           950:        port = DART_PORT(dev);
        !           951: #else
        !           952:        port = CONS_PORT;
        !           953: #endif
        !           954:        ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
        !           955:
        !           956:        s = spltty();
        !           957:
        !           958:        /* inhibit interrupts on the chip */
        !           959:        dart_cnwrite(DART_IMR, dartcn_sv.sv_imr &
        !           960:            (CONS_PORT == A_PORT ? ~ITXRDYA : ~ITXRDYB));
        !           961:        /* make sure transmitter is enabled */
        !           962: #if 0
        !           963:        DELAY_CR;
        !           964: #endif
        !           965:        dart_cnwrite(ptaddr + DART_CRA, TXEN);
        !           966:
        !           967:        while ((dart_cnread(ptaddr + DART_SRA) & TXRDY) == 0)
        !           968:                ;
        !           969:        dart_cnwrite(ptaddr + DART_TBA, c);
        !           970:
        !           971:        /* wait for transmitter to empty */
        !           972:        while ((dart_cnread(ptaddr + DART_SRA) & TXEMT) == 0)
        !           973:                ;
        !           974:
        !           975:        /* restore the previous state */
        !           976:        dart_cnwrite(DART_IMR, dartcn_sv.sv_imr);
        !           977: #if 0
        !           978:        DELAY_CR;
        !           979: #endif
        !           980:        dart_cnwrite(ptaddr + DART_CRA, dartcn_sv.sv_cr[0]);
        !           981:
        !           982:        splx(s);
        !           983: }
        !           984:
        !           985: int
        !           986: dartcngetc(dev_t dev)
        !           987: {
        !           988: #ifdef USE_PROM_CONSOLE
        !           989:        struct dartsoftc *sc;
        !           990: #endif
        !           991:        unsigned char sr;       /* status reg of port a/b */
        !           992:        u_char c;               /* received character */
        !           993:        int s;
        !           994:        u_int port;
        !           995:        bus_addr_t ptaddr;
        !           996:
        !           997: #ifdef USE_PROM_CONSOLE
        !           998:        sc = (struct dartsoftc *)dart_cd.cd_devs[0];
        !           999:        port = DART_PORT(dev);
        !          1000: #else
        !          1001:        port = CONS_PORT;
        !          1002: #endif
        !          1003:        ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
        !          1004:
        !          1005:        s = spltty();
        !          1006:
        !          1007:        /* enable receiver */
        !          1008:        dart_cnwrite(ptaddr + DART_CRA, RXEN);
        !          1009:
        !          1010:        for (;;) {
        !          1011:                /* read status reg */
        !          1012:                sr = dart_cnread(ptaddr + DART_SRA);
        !          1013:
        !          1014:                /* receiver interrupt handler*/
        !          1015:                if (sr & RXRDY) {
        !          1016:                        /* read character from port */
        !          1017:                        c = dart_cnread(ptaddr + DART_RBA);
        !          1018:
        !          1019:                        /* check break condition */
        !          1020:                        if (sr & RBRK) {
        !          1021:                                /* clear break state */
        !          1022:                                dart_cnwrite(ptaddr + DART_CRA, BRKINTRESET);
        !          1023:                                DELAY_CR;
        !          1024:                                dart_cnwrite(ptaddr + DART_CRA, ERRRESET);
        !          1025:                                break;
        !          1026:                        }
        !          1027:
        !          1028:                        if (sr & (FRERR | PERR | ROVRN)) {
        !          1029:                                /* clear error state */
        !          1030:                                dart_cnwrite(ptaddr + DART_CRA, ERRRESET);
        !          1031:                        } else {
        !          1032:                                break;
        !          1033:                        }
        !          1034:                }
        !          1035:        }
        !          1036:        splx(s);
        !          1037:
        !          1038:        return ((int)c);
        !          1039: }

CVSweb