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

Annotation of sys/arch/mvme88k/dev/dart.c, Revision 1.1.1.1

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

CVSweb