[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

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