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

Annotation of sys/arch/mvme68k/dev/cl.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: cl.c,v 1.43 2006/06/11 20:46:50 miod Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 1995 Dale Rahn. All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     17:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     18:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     19:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     20:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     21:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     22:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     23:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     24:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
                     27: /* DMA mode still does not work!!! */
                     28:
                     29: #include <sys/param.h>
                     30: #include <sys/ioctl.h>
                     31: #include <sys/proc.h>
                     32: #include <sys/tty.h>
                     33: #include <sys/uio.h>
                     34: #include <sys/systm.h>
                     35: #include <sys/time.h>
                     36: #include <sys/device.h>
                     37: #include <sys/syslog.h>
                     38:
                     39: #include <machine/autoconf.h>
                     40: #include <machine/conf.h>
                     41: #include <machine/cpu.h>
                     42:
                     43: #include <dev/cons.h>
                     44:
                     45: #include <mvme68k/dev/clreg.h>
                     46:
                     47: #include "cl.h"
                     48:
                     49: #ifdef DDB
                     50: #include <ddb/db_var.h>
                     51: #endif
                     52:
                     53: #include "pcctwo.h"
                     54:
                     55: #if NPCCTWO > 0
                     56: #include <mvme68k/dev/pcctworeg.h>
                     57: #endif
                     58:
                     59: #define splcl() spltty()
                     60: #define USE_BUFFER
                     61:
                     62: /* min timeout 0xa, what is a good value */
                     63: #define CL_TIMEOUT     0x10
                     64: #define CL_FIFO_MAX    0x10
                     65: #define CL_FIFO_CNT    0xc
                     66: #define        CL_RX_TIMEOUT   0x10
                     67:
                     68: #define CL_RXDMAINT    0x82
                     69: #define CL_TXDMAINT    0x42
                     70: #define CL_TXMASK      0x47
                     71: #define CL_RXMASK      0x87
                     72: #define CL_TXINTR      0x02
                     73: #define CL_RXINTR      0x02
                     74:
                     75: struct cl_cons {
                     76:        paddr_t cl_paddr;
                     77:        struct clreg *cl_vaddr;
                     78:        volatile struct pcctworeg *pcctwoaddr;
                     79:        u_char  channel;
                     80: } cl_cons;
                     81:
                     82: struct cl_info {
                     83:        struct tty *tty;
                     84:        u_char  cl_swflags;
                     85:        u_char  cl_softchar;
                     86:        u_char  cl_consio;
                     87:        u_char  cl_speed;
                     88:        u_char  cl_parstop;     /* parity, stop bits. */
                     89:        u_char  cl_rxmode;
                     90:        u_char  cl_txmode;
                     91:        u_char  cl_clen;
                     92:        u_char  cl_parity;
                     93:        u_char  transmitting;
                     94:        u_long  txcnt;
                     95:        u_long  rxcnt;
                     96:
                     97:        void *rx[2];
                     98:        void *rxp[2];
                     99:        void *tx[2];
                    100:        void *txp[2];
                    101:
                    102:        volatile u_char *pconsum;
                    103:        volatile u_char *psupply;
                    104:        volatile u_char *buffer;
                    105:        volatile int    nchar;
                    106: };
                    107: #define CLCD_PORTS_PER_CHIP 4
                    108: #define CL_BUFSIZE 256
                    109:
                    110: #ifndef DO_MALLOC
                    111: /* four (4) buffers per port */
                    112: char cl_dmabuf [CLCD_PORTS_PER_CHIP * CL_BUFSIZE * 4];
                    113: #endif
                    114:
                    115: struct clsoftc {
                    116:        struct device   sc_dev;
                    117:        time_t  sc_rotime;      /* time of last ring overrun */
                    118:        time_t  sc_fotime;      /* time of last fifo overrun */
                    119:        u_char *pbase;
                    120:        struct clreg *cl_reg;
                    121:        struct cl_info          sc_cl[CLCD_PORTS_PER_CHIP];
                    122:        struct intrhand         sc_ih_e;
                    123:        struct intrhand         sc_ih_m;
                    124:        struct intrhand         sc_ih_t;
                    125:        struct intrhand         sc_ih_r;
                    126:        char                    sc_errintrname[16 + 4];
                    127:        char                    sc_mxintrname[16 + 3];
                    128:        char                    sc_rxintrname[16 + 3];
                    129:        char                    sc_txintrname[16 + 3];
                    130:        int                     sc_flags;
                    131:        u_int8_t                ssir;
                    132: };
                    133:
                    134: const struct {
                    135:        u_int speed;
                    136:        u_char divisor;
                    137:        u_char clock;
                    138:        u_char rx_timeout;
                    139: } cl_clocks[] = {
                    140:        { 64000, 0x26, 0, 0x01},
                    141:        { 56000, 0x2c, 0, 0x01},
                    142:        { 38400, 0x40, 0, 0x01},
                    143:        { 19200, 0x81, 0, 0x02},
                    144:        {  9600, 0x40, 1, 0x04},
                    145:        {  7200, 0x56, 1, 0x04},
                    146:        {  4800, 0x81, 1, 0x08},
                    147:        {  3600, 0xad, 1, 0x08},
                    148:        {  2400, 0x40, 2, 0x10},
                    149:        {  1200, 0x81, 2, 0x20},
                    150:        {   600, 0x40, 3, 0x40},
                    151:        {   300, 0x81, 3, 0x80},
                    152:        {   150, 0x40, 3, 0x80},
                    153:        {   110, 0x58, 4, 0xff},
                    154:        {    50, 0xC2, 4, 0xff},
                    155:        {     0, 0x00, 0, 0},
                    156: };
                    157:
                    158: /* prototypes */
                    159: cons_decl(cl);
                    160: u_char cl_clkdiv(int speed);
                    161: u_char cl_clknum(int speed);
                    162: u_char cl_clkrxtimeout(int speed);
                    163: void clstart(struct tty *tp);
                    164: void cl_unblock(struct tty *tp);
                    165: int clccparam(struct clsoftc *sc, struct termios *par, int channel);
                    166:
                    167: int clparam(struct tty *tp, struct termios *t);
                    168: int cl_mintr(void *);
                    169: int cl_txintr(void *);
                    170: int cl_rxintr(void *);
                    171: void cl_overflow(struct clsoftc *sc, int channel, time_t *ptime, u_char *msg);
                    172: void cl_parity(struct clsoftc *sc, int channel);
                    173: void cl_frame(struct clsoftc *sc, int channel);
                    174: void cl_break( struct clsoftc *sc, int channel);
                    175: int clmctl(dev_t dev, int bits, int how);
                    176: void cl_dumpport(int channel);
                    177:
                    178: int    clprobe(struct device *parent, void *self, void *aux);
                    179: void   clattach(struct device *parent, struct device *self, void *aux);
                    180:
                    181: void cl_initchannel(struct clsoftc *sc, int channel);
                    182: void clputc(struct clsoftc *sc, int unit, u_char c);
                    183: u_char clgetc(struct clsoftc *sc, int *channel);
                    184: void cloutput(struct tty *tp);
                    185: void cl_softint(void *);
                    186: void cl_appendbufn(struct clsoftc *sc, u_char channel, u_char *buf, u_short cnt);
                    187:
                    188: struct tty *cltty(dev_t);
                    189: int cl_instat(struct clsoftc *);
                    190: void clcnpollc(dev_t, int);
                    191: void cl_break(struct clsoftc *, int);
                    192: void cl_appendbuf(struct clsoftc *, u_char, u_char);
                    193:
                    194: struct cfattach cl_ca = {
                    195:        sizeof(struct clsoftc), clprobe, clattach
                    196: };
                    197:
                    198: struct cfdriver cl_cd = {
                    199:        NULL, "cl", DV_TTY
                    200: };
                    201:
                    202: #define CLCDBUF 80
                    203:
                    204: #define CL_UNIT(x) (minor(x) >> 2)
                    205: #define CL_CHANNEL(x) (minor(x) & 3)
                    206: #define CL_TTY(x) (minor(x))
                    207:
                    208: struct tty *
                    209: cltty(dev)
                    210:        dev_t dev;
                    211: {
                    212:        int unit, channel;
                    213:        struct clsoftc *sc;
                    214:        unit = CL_UNIT(dev);
                    215:        if (unit >= cl_cd.cd_ndevs ||
                    216:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                    217:                return (NULL);
                    218:        }
                    219:        channel = CL_CHANNEL(dev);
                    220:        return sc->sc_cl[channel].tty;
                    221: }
                    222:
                    223: int
                    224: clprobe(parent, self, aux)
                    225:        struct device *parent;
                    226:        void *self;
                    227:        void *aux;
                    228: {
                    229:        /* probing onboard 166/167/177/187 CL-cd2400
                    230:         * should be previously configured,
                    231:         * we can check the value before resetting the chip
                    232:         */
                    233:        struct clreg *cl_reg;
                    234:        struct confargs *ca = aux;
                    235:        int ret;
                    236:        if (cputyp != CPU_167 && cputyp != CPU_166 && cputyp != CPU_177)
                    237:        {
                    238:                return 0;
                    239:        }
                    240:    cl_reg = (struct clreg *)ca->ca_vaddr;
                    241:
                    242: #if 0
                    243:        ret = !badvaddr(&cl_reg->cl_gfrcr,1);
                    244: #else
                    245:        ret = 1;
                    246: #endif
                    247:        return ret;
                    248: }
                    249:
                    250: void
                    251: clattach(parent, self, aux)
                    252:        struct device *parent;
                    253:        struct device *self;
                    254:        void *aux;
                    255: {
                    256:        struct clsoftc *sc = (struct clsoftc *)self;
                    257:        struct confargs *ca = aux;
                    258:        int i;
                    259:
                    260:        sc->cl_reg = (struct clreg *)ca->ca_vaddr;
                    261:
                    262:        if (ca->ca_paddr == cl_cons.cl_paddr) {
                    263:                /* if this device is configured as console,
                    264:                 * line cl_cons.channel is the console */
                    265:                sc->sc_cl[0].cl_consio = 1;
                    266:                printf(": console");
                    267:        } else {
                    268:                /* reset chip only if we are not console device */
                    269:                /* wait for GFRCR */
                    270:        }
                    271:         /* allow chip to settle before continuing */
                    272:         delay(800);
                    273:
                    274:        /* set up global registers */
                    275:        sc->cl_reg->cl_tpr = CL_TIMEOUT;
                    276:        sc->cl_reg->cl_rpilr = 0x03;
                    277:        sc->cl_reg->cl_tpilr = 0x02;
                    278:        sc->cl_reg->cl_mpilr = 0x01;
                    279:
                    280: #ifdef DO_MALLOC
                    281:        sc->sc_cl[0].rx[0] = (void *)(dvma_malloc(16 * CL_BUFSIZE));
                    282: #else
                    283:        sc->sc_cl[0].rx[0] = (void *) (&cl_dmabuf);
                    284: #endif
                    285:        sc->sc_cl[0].rx[1] = (void *)(((int)sc->sc_cl[0].rx[0]) + CL_BUFSIZE);
                    286:        sc->sc_cl[1].rx[0] = (void *)(((int)sc->sc_cl[0].rx[1]) + CL_BUFSIZE);
                    287:        sc->sc_cl[1].rx[1] = (void *)(((int)sc->sc_cl[1].rx[0]) + CL_BUFSIZE);
                    288:
                    289:        sc->sc_cl[2].rx[0] = (void *)(((int)sc->sc_cl[1].rx[1]) + CL_BUFSIZE);
                    290:        sc->sc_cl[2].rx[1] = (void *)(((int)sc->sc_cl[2].rx[0]) + CL_BUFSIZE);
                    291:        sc->sc_cl[3].rx[0] = (void *)(((int)sc->sc_cl[2].rx[1]) + CL_BUFSIZE);
                    292:        sc->sc_cl[3].rx[1] = (void *)(((int)sc->sc_cl[3].rx[0]) + CL_BUFSIZE);
                    293:
                    294:        sc->sc_cl[0].tx[0] = (void *)(((int)sc->sc_cl[3].rx[1]) + CL_BUFSIZE);
                    295:        sc->sc_cl[0].tx[1] = (void *)(((int)sc->sc_cl[0].tx[0]) + CL_BUFSIZE);
                    296:        sc->sc_cl[1].tx[0] = (void *)(((int)sc->sc_cl[0].tx[1]) + CL_BUFSIZE);
                    297:        sc->sc_cl[1].tx[1] = (void *)(((int)sc->sc_cl[1].tx[0]) + CL_BUFSIZE);
                    298:
                    299:        sc->sc_cl[2].tx[0] = (void *)(((int)sc->sc_cl[1].tx[1]) + CL_BUFSIZE);
                    300:        sc->sc_cl[2].tx[1] = (void *)(((int)sc->sc_cl[2].tx[0]) + CL_BUFSIZE);
                    301:        sc->sc_cl[3].tx[0] = (void *)(((int)sc->sc_cl[2].tx[1]) + CL_BUFSIZE);
                    302:        sc->sc_cl[3].tx[1] = (void *)(((int)sc->sc_cl[3].tx[0]) + CL_BUFSIZE);
                    303: #ifdef USE_BUFFER
                    304:        /* receive buffer and dma buffer are "shared" */
                    305:        for (i = 0; i < CLCD_PORTS_PER_CHIP; i++) {
                    306:                sc->sc_cl[i].buffer = sc->sc_cl[i].rx[0];
                    307:                sc->sc_cl[i].pconsum = sc->sc_cl[i].buffer;
                    308:                sc->sc_cl[i].psupply = sc->sc_cl[i].buffer;
                    309:                sc->sc_cl[i].nchar = 0;
                    310:        }
                    311:        sc->ssir = allocate_sir(cl_softint, (void *)sc);
                    312: #endif
                    313:        for (i = 0; i < CLCD_PORTS_PER_CHIP; i++) {
                    314: #if 0
                    315:                int j;
                    316:
                    317:                for (j = 0; j < 2 ; j++) {
                    318:                        sc->sc_cl[i].rxp[j] = (void *)kvtop(sc->sc_cl[i].rx[j]);
                    319:                        printf("cl[%d].rxbuf[%d] %x p %x\n",
                    320:                            i, j, sc->sc_cl[i].rx[j], sc->sc_cl[i].rxp[j]);
                    321:                        sc->sc_cl[i].txp[j] = (void *)kvtop(sc->sc_cl[i].tx[j]);
                    322:                        printf("cl[%d].txbuf[%d] %x p %x\n",
                    323:                            i, j, sc->sc_cl[i].tx[j], sc->sc_cl[i].txp[j]);
                    324:                }
                    325: #endif
                    326:
                    327: #if 0
                    328:                sc->sc_cl[i].cl_rxmode =
                    329:                        !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x01));
                    330:                sc->sc_cl[i].cl_txmode =
                    331:                        !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x02));
                    332:                sc->sc_cl[i].cl_softchar =
                    333:                        !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x04));
                    334: #endif
                    335:                cl_initchannel(sc, i);
                    336:        }
                    337:
                    338:        /* enable interrupts */
                    339:        sc->sc_ih_e.ih_fn = cl_rxintr;
                    340:        sc->sc_ih_e.ih_arg = sc;
                    341:        sc->sc_ih_e.ih_ipl = ca->ca_ipl;
                    342:        sc->sc_ih_e.ih_wantframe = 0;
                    343:
                    344:        sc->sc_ih_m.ih_fn = cl_mintr;
                    345:        sc->sc_ih_m.ih_arg = sc;
                    346:        sc->sc_ih_m.ih_ipl = ca->ca_ipl;
                    347:        sc->sc_ih_m.ih_wantframe = 0;
                    348:
                    349:        sc->sc_ih_t.ih_fn = cl_txintr;
                    350:        sc->sc_ih_t.ih_arg = sc;
                    351:        sc->sc_ih_t.ih_ipl = ca->ca_ipl;
                    352:        sc->sc_ih_t.ih_wantframe = 0;
                    353:
                    354:        sc->sc_ih_r.ih_fn = cl_rxintr;
                    355:        sc->sc_ih_r.ih_arg = sc;
                    356:        sc->sc_ih_r.ih_ipl = ca->ca_ipl;
                    357:        sc->sc_ih_r.ih_wantframe = 0;
                    358:
                    359:        snprintf(sc->sc_errintrname, sizeof sc->sc_errintrname,
                    360:            "%s_err", self->dv_xname);
                    361:        snprintf(sc->sc_mxintrname, sizeof sc->sc_mxintrname,
                    362:            "%s_mx", self->dv_xname);
                    363:        snprintf(sc->sc_rxintrname, sizeof sc->sc_rxintrname,
                    364:            "%s_rx", self->dv_xname);
                    365:        snprintf(sc->sc_txintrname, sizeof sc->sc_txintrname,
                    366:            "%s_tx", self->dv_xname);
                    367:
                    368:        pcctwointr_establish(PCC2V_SCC_RXE,&sc->sc_ih_e, sc->sc_errintrname);
                    369:        pcctwointr_establish(PCC2V_SCC_M,&sc->sc_ih_m, sc->sc_mxintrname);
                    370:        pcctwointr_establish(PCC2V_SCC_TX,&sc->sc_ih_t, sc->sc_txintrname);
                    371:        pcctwointr_establish(PCC2V_SCC_RX,&sc->sc_ih_r, sc->sc_rxintrname);
                    372:        sys_pcc2->pcc2_sccerr = 0x01; /* clear errors */
                    373:
                    374:        /* enable all interrupts at ca_ipl */
                    375:        sys_pcc2->pcc2_sccirq = PCC2_IRQ_IEN | (ca->ca_ipl & 0x7);
                    376:        sys_pcc2->pcc2_scctx  = PCC2_IRQ_IEN | (ca->ca_ipl & 0x7);
                    377:        sys_pcc2->pcc2_sccrx  = PCC2_IRQ_IEN | (ca->ca_ipl & 0x7);
                    378:
                    379:        printf("\n");
                    380: }
                    381:
                    382: void
                    383: cl_initchannel(sc, channel)
                    384:        struct clsoftc *sc;
                    385:        int channel;
                    386: {
                    387:        int s;
                    388:        struct clreg *cl_reg = sc->cl_reg;
                    389:
                    390:        /* set up option registers */
                    391:        sc->sc_cl[channel].tty = NULL;
                    392:        s = splhigh();
                    393:
                    394:        cl_reg->cl_car  = (u_char) channel;
                    395:        cl_reg->cl_livr = PCC2_VECBASE + 0xc;/* set vector base at 5C */
                    396:        cl_reg->cl_ier  = 0x00;
                    397:
                    398:        if (sc->sc_cl[channel].cl_consio == 0) {
                    399:                cl_reg->cl_cmr  = 0x02;
                    400:                cl_reg->cl_cor1 = 0x17;
                    401:                cl_reg->cl_cor2 = 0x00;
                    402:                cl_reg->cl_cor3 = 0x02;
                    403:                cl_reg->cl_cor4 = 0xec;
                    404:                cl_reg->cl_cor5 = 0xec;
                    405:                cl_reg->cl_cor6 = 0x00;
                    406:                cl_reg->cl_cor7 = 0x00;
                    407:                cl_reg->cl_schr1        = 0x00;
                    408:                cl_reg->cl_schr2        = 0x00;
                    409:                cl_reg->cl_schr3        = 0x00;
                    410:                cl_reg->cl_schr4        = 0x00;
                    411:                cl_reg->cl_scrl = 0x00;
                    412:                cl_reg->cl_scrh = 0x00;
                    413:                cl_reg->cl_lnxt = 0x00;
                    414:                cl_reg->cl_rbpr = 0x40; /* 9600 */
                    415:                cl_reg->cl_rcor = 0x01;
                    416:                cl_reg->cl_tbpr = 0x40; /* 9600 */
                    417:                cl_reg->cl_tcor = 0x01 << 5;
                    418:                /* console port should be 0x88 already */
                    419:                cl_reg->cl_msvr_rts     = 0x00;
                    420:                cl_reg->cl_msvr_dtr     = 0x00;
                    421:                cl_reg->cl_rtprl        = CL_RX_TIMEOUT;
                    422:                cl_reg->cl_rtprh        = 0x00;
                    423:
                    424:                sc->cl_reg->cl_ccr = 0x20;
                    425:                while (sc->cl_reg->cl_ccr != 0)
                    426:                        ;
                    427:        }
                    428:
                    429:        splx(s);
                    430: }
                    431:
                    432:
                    433: int cldefaultrate = TTYDEF_SPEED;
                    434:
                    435: int clmctl (dev, bits, how)
                    436:        dev_t dev;
                    437:        int bits;
                    438:        int how;
                    439: {
                    440:        int s;
                    441:        struct clsoftc *sc;
                    442:        /* should only be called with valid device */
                    443:        sc = (struct clsoftc *) cl_cd.cd_devs[CL_UNIT(dev)];
                    444:        /*
                    445:        printf("mctl: dev %x, bits %x, how %x,\n",dev, bits, how);
                    446:        */
                    447:        /* settings are currently ignored */
                    448:        s = splcl();
                    449:        switch (how) {
                    450:        case DMSET:
                    451:                if( bits & TIOCM_RTS) {
                    452:                        sc->cl_reg->cl_msvr_rts = 0x01;
                    453:                } else {
                    454:                        sc->cl_reg->cl_msvr_rts = 0x00;
                    455:                }
                    456:                if( bits & TIOCM_DTR) {
                    457:                        sc->cl_reg->cl_msvr_dtr = 0x02;
                    458:                } else {
                    459:                        sc->cl_reg->cl_msvr_dtr = 0x00;
                    460:                }
                    461:                break;
                    462:
                    463:        case DMBIC:
                    464:                if( bits & TIOCM_RTS) {
                    465:                        sc->cl_reg->cl_msvr_rts = 0x00;
                    466:                }
                    467:                if( bits & TIOCM_DTR) {
                    468:                        sc->cl_reg->cl_msvr_dtr = 0x00;
                    469:                }
                    470:                break;
                    471:
                    472:        case DMBIS:
                    473:                if( bits & TIOCM_RTS) {
                    474:                        sc->cl_reg->cl_msvr_rts = 0x01;
                    475:                }
                    476:                if( bits & TIOCM_DTR) {
                    477:                        sc->cl_reg->cl_msvr_dtr = 0x02;
                    478:                }
                    479:                break;
                    480:
                    481:        case DMGET:
                    482:                bits = 0;
                    483:
                    484:                {
                    485:                        u_char msvr;
                    486:                        msvr = sc->cl_reg->cl_msvr_rts;
                    487:                        if( msvr & 0x80) {
                    488:                                bits |= TIOCM_DSR;
                    489:                        }
                    490:                        if( msvr & 0x40) {
                    491:                                bits |= TIOCM_CD;
                    492:                        }
                    493:                        if( msvr & 0x20) {
                    494:                                bits |= TIOCM_CTS;
                    495:                        }
                    496:                        if( msvr & 0x10) {
                    497:                                bits |= TIOCM_DTR;
                    498:                        }
                    499:                        if( msvr & 0x02) {
                    500:                                bits |= TIOCM_DTR;
                    501:                        }
                    502:                        if( msvr & 0x01) {
                    503:                                bits |= TIOCM_RTS;
                    504:                        }
                    505:
                    506:                }
                    507:                break;
                    508:        }
                    509:        splx(s);
                    510: #if 0
                    511:        bits = 0;
                    512:        /* proper defaults? */
                    513:        bits |= TIOCM_DTR;
                    514:        bits |= TIOCM_RTS;
                    515:        bits |= TIOCM_CTS;
                    516:        bits |= TIOCM_CD;
                    517:        /*      bits |= TIOCM_RI; */
                    518:        bits |= TIOCM_DSR;
                    519: #endif
                    520:
                    521:        /*
                    522:        printf("retbits %x\n", bits);
                    523:        */
                    524:        return(bits);
                    525: }
                    526:
                    527: int
                    528: clopen(dev, flag, mode, p)
                    529:        dev_t dev;
                    530:        int flag;
                    531:        int mode;
                    532:        struct proc *p;
                    533: {
                    534:        int s, unit, channel;
                    535:        struct cl_info *cl;
                    536:        struct clsoftc *sc;
                    537:        struct tty *tp;
                    538:
                    539:        unit = CL_UNIT(dev);
                    540:        if (unit >= cl_cd.cd_ndevs ||
                    541:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                    542:                return (ENODEV);
                    543:        }
                    544:        channel = CL_CHANNEL(dev);
                    545:        cl = &sc->sc_cl[channel];
                    546:        s = splcl();
                    547:        if (cl->tty) {
                    548:                tp = cl->tty;
                    549:        } else {
                    550:                tp = cl->tty = ttymalloc();
                    551:        }
                    552:        tp->t_oproc = clstart;
                    553:        tp->t_param = clparam;
                    554:        tp->t_dev = dev;
                    555:
                    556:        if ((tp->t_state & TS_ISOPEN) == 0) {
                    557:                tp->t_state |= TS_WOPEN;
                    558:                ttychars(tp);
                    559:                if (tp->t_ispeed == 0) {
                    560:                        /*
                    561:                         * only when cleared do we reset to defaults.
                    562:                         */
                    563:                        tp->t_iflag = TTYDEF_IFLAG;
                    564:                        tp->t_oflag = TTYDEF_OFLAG;
                    565:                        tp->t_lflag = TTYDEF_LFLAG;
                    566:                        tp->t_ispeed = tp->t_ospeed = cldefaultrate;
                    567:
                    568:                        if(sc->sc_cl[channel].cl_consio != 0) {
                    569:                                /* console is 8N1 */
                    570:                                tp->t_cflag = (CREAD | CS8 | HUPCL);
                    571:                        } else {
                    572:                                tp->t_cflag = TTYDEF_CFLAG;
                    573:                        }
                    574:                }
                    575:                /*
                    576:                 * do these all the time
                    577:                 */
                    578:                if (cl->cl_swflags & TIOCFLAG_CLOCAL)
                    579:                        tp->t_cflag |= CLOCAL;
                    580:                if (cl->cl_swflags & TIOCFLAG_CRTSCTS)
                    581:                        tp->t_cflag |= CRTSCTS;
                    582:                if (cl->cl_swflags & TIOCFLAG_MDMBUF)
                    583:                        tp->t_cflag |= MDMBUF;
                    584:                clparam(tp, &tp->t_termios);
                    585:                ttsetwater(tp);
                    586:
                    587:                (void)clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
                    588: #ifdef XXX
                    589:                if ((cl->cl_swflags & TIOCFLAG_SOFTCAR) ||
                    590:                        (clmctl(dev, 0, DMGET) & TIOCM_CD)) {
                    591:                        tp->t_state |= TS_CARR_ON;
                    592:                } else {
                    593:                        tp->t_state &= ~TS_CARR_ON;
                    594:                }
                    595: #endif
                    596:                tp->t_state |= TS_CARR_ON;
                    597:                {
                    598:                        u_char save = sc->cl_reg->cl_car;
                    599:                        sc->cl_reg->cl_car = channel;
                    600:                        sc->cl_reg->cl_ier      = 0x88;
                    601: #ifdef CL_DMA_WORKS
                    602:                        {
                    603:                        sc->cl_reg->cl_cmr      =
                    604:                                /* CL_TXDMAINT | */ CL_RXDMAINT;
                    605:                        sc->cl_reg->cl_ier      = 0xa8;
                    606:                        sc->cl_reg->cl_licr     = 0x00;
                    607:                        }
                    608:                        sc->cl_reg->cl_arbadrl  =
                    609:                                ((u_long)sc->sc_cl[channel].rxp[0]) & 0xffff;
                    610:                        sc->cl_reg->cl_arbadru  =
                    611:                                ((u_long)sc->sc_cl[channel].rxp[0]) >> 16;
                    612:                        sc->cl_reg->cl_brbadrl  =
                    613:                                ((u_long)sc->sc_cl[channel].rxp[1]) & 0xffff;
                    614:                        sc->cl_reg->cl_brbadru  =
                    615:                                ((u_long)sc->sc_cl[channel].rxp[1]) >> 16;
                    616:                        sc->cl_reg->cl_atbadrl  =
                    617:                                ((u_long)sc->sc_cl[channel].txp[0]) & 0xffff;
                    618:                        sc->cl_reg->cl_atbadru  =
                    619:                                ((u_long)sc->sc_cl[channel].txp[0]) >> 16;
                    620:                        sc->cl_reg->cl_btbadrl  =
                    621:                                ((u_long)sc->sc_cl[channel].txp[1]) & 0xffff;
                    622:                        sc->cl_reg->cl_btbadru  =
                    623:                                ((u_long)sc->sc_cl[channel].txp[1]) >> 16;
                    624:                        sc->cl_reg->cl_arbcnt   = CL_BUFSIZE;
                    625:                        sc->cl_reg->cl_brbcnt   = CL_BUFSIZE;
                    626:                        sc->cl_reg->cl_arbsts   = 0x01;
                    627:                        sc->cl_reg->cl_brbsts   = 0x01;
                    628: if (channel == 2) { /* test one channel now */
                    629:                        /* shift for tx DMA */
                    630:                        /* no shift for rx DMA */
                    631: #if 0
                    632:                        /* tx only */
                    633:                        sc->cl_reg->cl_licr     = (CL_DMAMODE << 4);
                    634:                        sc->cl_reg->cl_cmr      = 0x42;
                    635: #endif
                    636:                /* rx only */
                    637:                        sc->cl_reg->cl_licr     = 0x00;
                    638:                        sc->cl_reg->cl_cmr      = 0x82;
                    639: }
                    640:                        sc->cl_reg->cl_ccr = 0x20;
                    641:                        while (sc->cl_reg->cl_ccr != 0) {
                    642:                        }
                    643: #endif /* CL_DMA_WORKS */
                    644:                        sc->cl_reg->cl_car = save;
                    645:                }
                    646:        } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
                    647:                splx(s);
                    648:                return(EBUSY);
                    649:        }
                    650: #ifdef XXX
                    651:        /*
                    652:         * if NONBLOCK requested, ignore carrier
                    653:         */
                    654:        if (flag & O_NONBLOCK)
                    655:        goto done;
                    656: #endif
                    657:
                    658:        splx(s);
                    659:        /*
                    660:         * Reset the tty pointer, as there could have been a dialout
                    661:         * use of the tty with a dialin open waiting.
                    662:         */
                    663:        tp->t_dev = dev;
                    664: #ifdef DEBUG
                    665:        cl_dumpport(channel);
                    666: #endif
                    667:        return((*linesw[tp->t_line].l_open)(dev, tp));
                    668: }
                    669: int clparam(tp, t)
                    670:        struct tty *tp;
                    671:        struct termios *t;
                    672: {
                    673:        int unit, channel;
                    674:        struct clsoftc *sc;
                    675:        int s;
                    676:        dev_t dev;
                    677:
                    678:        dev = tp->t_dev;
                    679:        unit = CL_UNIT(dev);
                    680:        if (unit >= cl_cd.cd_ndevs ||
                    681:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                    682:                return (ENODEV);
                    683:        }
                    684:        channel = CL_CHANNEL(dev);
                    685:        tp->t_ispeed = t->c_ispeed;
                    686:        tp->t_ospeed = t->c_ospeed;
                    687:        tp->t_cflag = t->c_cflag;
                    688:        clccparam(sc, t, channel);
                    689:        s = splcl();
                    690:        cl_unblock(tp);
                    691:        splx(s);
                    692:        return 0;
                    693: }
                    694:
                    695: #if 0
                    696: void cloutput(tp)
                    697:        struct tty *tp;
                    698: {
                    699:        int cc, s, unit, cnt;
                    700:        u_char *tptr;
                    701:        int channel;
                    702:        struct clsoftc *sc;
                    703:        dev_t dev;
                    704:        u_char cl_obuffer[CLCDBUF+1];
                    705:
                    706:        dev = tp->t_dev;
                    707:        unit = CL_UNIT(dev);
                    708:        if (unit >= cl_cd.cd_ndevs ||
                    709:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                    710:                return;
                    711:        }
                    712:        channel = CL_CHANNEL(dev);
                    713:
                    714:        if ((tp->t_state & TS_ISOPEN) == 0)
                    715:                return;
                    716:
                    717:        s = splcl();
                    718:        cc = tp->t_outq.c_cc;
                    719:        while (cc > 0) {
                    720: /*XXX*/
                    721:                cnt = min (CLCDBUF,cc);
                    722:                cnt = q_to_b(&tp->t_outq, cl_obuffer, cnt);
                    723:                if (cnt == 0) {
                    724:                        break;
                    725:                }
                    726:                for (tptr = cl_obuffer; tptr < &cl_obuffer[cnt]; tptr++) {
                    727:                        clputc(sc, channel, *tptr);
                    728:                }
                    729:                cc -= cnt;
                    730:        }
                    731:        splx(s);
                    732: }
                    733: #endif
                    734:
                    735: int
                    736: clclose(dev, flag, mode, p)
                    737:        dev_t dev;
                    738:        int flag;
                    739:        int mode;
                    740:        struct proc *p;
                    741: {
                    742:        int unit, channel;
                    743:        struct tty *tp;
                    744:        struct cl_info *cl;
                    745:        struct clsoftc *sc;
                    746:        int s;
                    747:        unit = CL_UNIT(dev);
                    748:        if (unit >= cl_cd.cd_ndevs ||
                    749:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                    750:                return (ENODEV);
                    751:        }
                    752:        channel = CL_CHANNEL(dev);
                    753:        cl = &sc->sc_cl[channel];
                    754:        tp = cl->tty;
                    755:        (*linesw[tp->t_line].l_close)(tp, flag);
                    756:
                    757:        s = splcl();
                    758:
                    759:        sc->cl_reg->cl_car = channel;
                    760:        if(cl->cl_consio == 0 && (tp->t_cflag & HUPCL) != 0) {
                    761:                sc->cl_reg->cl_msvr_rts = 0x00;
                    762:                sc->cl_reg->cl_msvr_dtr = 0x00;
                    763:                sc->cl_reg->cl_ccr = 0x05;
                    764:        }
                    765:
                    766:        splx(s);
                    767:        ttyclose(tp);
                    768:
                    769: #if 0
                    770:        cl->tty = NULL;
                    771: #endif
                    772: #ifdef DEBUG
                    773:        cl_dumpport(channel);
                    774: #endif
                    775:
                    776:        return 0;
                    777: }
                    778:
                    779: int
                    780: clread (dev, uio, flag)
                    781:        dev_t dev;
                    782:        struct uio *uio;
                    783:        int flag;
                    784: {
                    785:        int unit, channel;
                    786:        struct tty *tp;
                    787:        struct cl_info *cl;
                    788:        struct clsoftc *sc;
                    789:        unit = CL_UNIT(dev);
                    790:        if (unit >= cl_cd.cd_ndevs ||
                    791:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                    792:                return (ENODEV);
                    793:        }
                    794:        channel = CL_CHANNEL(dev);
                    795:        cl = &sc->sc_cl[channel];
                    796:        tp = cl->tty;
                    797:        if (!tp)
                    798:                return ENXIO;
                    799:        return((*linesw[tp->t_line].l_read)(tp, uio, flag));
                    800: }
                    801:
                    802: int
                    803: clwrite (dev, uio, flag)
                    804:        dev_t dev;
                    805:        struct uio *uio;
                    806:        int flag;
                    807: {
                    808:        int unit, channel;
                    809:        struct tty *tp;
                    810:        struct cl_info *cl;
                    811:        struct clsoftc *sc;
                    812:        unit = CL_UNIT(dev);
                    813:        if (unit >= cl_cd.cd_ndevs ||
                    814:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                    815:                return (ENODEV);
                    816:        }
                    817:        channel = CL_CHANNEL(dev);
                    818:        cl = &sc->sc_cl[channel];
                    819:        tp = cl->tty;
                    820:        if (!tp)
                    821:                return ENXIO;
                    822:        return((*linesw[tp->t_line].l_write)(tp, uio, flag));
                    823: }
                    824:
                    825: int
                    826: clioctl(dev, cmd, data, flag, p)
                    827:        dev_t dev;
                    828:        u_long cmd;
                    829:        caddr_t data;
                    830:        int flag;
                    831:        struct proc *p;
                    832: {
                    833:        int error;
                    834:        int unit, channel;
                    835:        struct tty *tp;
                    836:        struct cl_info *cl;
                    837:        struct clsoftc *sc;
                    838:        unit = CL_UNIT(dev);
                    839:        if (unit >= cl_cd.cd_ndevs ||
                    840:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                    841:                return (ENODEV);
                    842:        }
                    843:        channel = CL_CHANNEL(dev);
                    844:        cl = &sc->sc_cl[channel];
                    845:        tp = cl->tty;
                    846:        if (!tp)
                    847:                return ENXIO;
                    848:
                    849:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
                    850:        if (error >= 0)
                    851:                return(error);
                    852:
                    853:        error = ttioctl(tp, cmd, data, flag, p);
                    854:        if (error >= 0)
                    855:                return(error);
                    856:
                    857:        switch (cmd) {
                    858:        case TIOCSBRK:
                    859:                /* */
                    860:                break;
                    861:
                    862:        case TIOCCBRK:
                    863:                /* */
                    864:                break;
                    865:
                    866:        case TIOCSDTR:
                    867:                (void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
                    868:                break;
                    869:
                    870:        case TIOCCDTR:
                    871:                (void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
                    872:                break;
                    873:
                    874:        case TIOCMSET:
                    875:                (void) clmctl(dev, *(int *) data, DMSET);
                    876:                break;
                    877:
                    878:        case TIOCMBIS:
                    879:                (void) clmctl(dev, *(int *) data, DMBIS);
                    880:                break;
                    881:
                    882:        case TIOCMBIC:
                    883:                (void) clmctl(dev, *(int *) data, DMBIC);
                    884:                break;
                    885:
                    886:        case TIOCMGET:
                    887:                *(int *)data = clmctl(dev, 0, DMGET);
                    888:                break;
                    889:        case TIOCGFLAGS:
                    890:                *(int *)data = cl->cl_swflags;
                    891:                break;
                    892:        case TIOCSFLAGS:
                    893:                error = suser(p, 0);
                    894:                if (error != 0)
                    895:                        return(EPERM);
                    896:
                    897:                cl->cl_swflags = *(int *)data;
                    898:                cl->cl_swflags &= /* only allow valid flags */
                    899:                        (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
                    900:                break;
                    901:        default:
                    902:                return(ENOTTY);
                    903:        }
                    904:
                    905:        return 0;
                    906: }
                    907: int
                    908: clstop(tp, flag)
                    909:        struct tty *tp;
                    910:        int flag;
                    911: {
                    912:        int s;
                    913:
                    914:        s = splcl();
                    915:        if (tp->t_state & TS_BUSY) {
                    916:                if ((tp->t_state & TS_TTSTOP) == 0)
                    917:                        tp->t_state |= TS_FLUSH;
                    918:        }
                    919:        splx(s);
                    920:        return 0;
                    921: }
                    922:
                    923: void
                    924: clcnprobe(cp)
                    925:        struct consdev *cp;
                    926: {
                    927:        int maj;
                    928:
                    929:        switch (cputyp) {
                    930:        case CPU_167:
                    931:        case CPU_177:
                    932:                break;
                    933:        default:
                    934:                return;
                    935:        }
                    936:
                    937:        /* locate the major number */
                    938:        for (maj = 0; maj < nchrdev; maj++)
                    939:                if (cdevsw[maj].d_open == clopen)
                    940:                        break;
                    941:        cp->cn_dev = makedev (maj, 0);
                    942:        cp->cn_pri = CN_NORMAL;
                    943: }
                    944:
                    945: void
                    946: clcninit(cp)
                    947:        struct consdev *cp;
                    948: {
                    949:        struct clreg *cl_reg;
                    950:
                    951:        cl_cons.cl_paddr = 0xfff45000;
                    952:        cl_cons.cl_vaddr = (struct clreg *)IIOV(cl_cons.cl_paddr);
                    953:        cl_cons.pcctwoaddr = (void *)IIOV(0xfff42000);
                    954:        cl_reg = cl_cons.cl_vaddr;
                    955:
                    956:        /* reset the chip? */
                    957: #ifdef CLCD_DO_RESET
                    958: #endif
                    959:
                    960: #if 1
                    961:        /* set up globals */
                    962:        cl_reg->cl_tftc  = 0x10;
                    963:        cl_reg->cl_tpr   = CL_TIMEOUT; /* is this correct?? */
                    964:        cl_reg->cl_rpilr = 0x03;
                    965:        cl_reg->cl_tpilr = 0x02;
                    966:        cl_reg->cl_mpilr = 0x01;
                    967:
                    968:        /* set up the tty00 to be 9600 8N1 */
                    969:        cl_reg->cl_car   = 0x00;
                    970:        cl_reg->cl_cor1  = 0x17;        /* No parity, ignore parity, 8 bit char */
                    971:        cl_reg->cl_cor2  = 0x00;
                    972:        cl_reg->cl_cor3  = 0x02;        /* 1 stop bit */
                    973:        cl_reg->cl_cor4  = 0x00;
                    974:        cl_reg->cl_cor5  = 0x00;
                    975:        cl_reg->cl_cor6  = 0x00;
                    976:        cl_reg->cl_cor7  = 0x00;
                    977:        cl_reg->cl_schr1 = 0x00;
                    978:        cl_reg->cl_schr2 = 0x00;
                    979:        cl_reg->cl_schr3 = 0x00;
                    980:        cl_reg->cl_schr4 = 0x00;
                    981:        cl_reg->cl_scrl  = 0x00;
                    982:        cl_reg->cl_scrh  = 0x00;
                    983:        cl_reg->cl_lnxt  = 0x00;
                    984:        cl_reg->cl_cpsr  = 0x00;
                    985: #endif
                    986: }
                    987:
                    988: int
                    989: cl_instat(sc)
                    990:        struct clsoftc *sc;
                    991: {
                    992:        struct clreg *cl_reg;
                    993:        if ( NULL == sc) {
                    994:                cl_reg = cl_cons.cl_vaddr;
                    995:        } else {
                    996:                cl_reg = sc->cl_reg;
                    997:        }
                    998:        return (cl_reg->cl_rir & 0x40);
                    999: }
                   1000: int
                   1001: clcngetc(dev)
                   1002:        dev_t dev;
                   1003: {
                   1004:        u_char val, reoir, licr, isrl, data, fifo_cnt;
                   1005: #if 0
                   1006:        u_char status;
                   1007: #endif
                   1008:        int got_char = 0;
                   1009:        u_char ier_old = 0xff;
                   1010:        struct clreg *cl_reg = cl_cons.cl_vaddr;
                   1011:        volatile struct pcctworeg *pcc2_base = cl_cons.pcctwoaddr;
                   1012:
                   1013:        cl_reg->cl_car = 0;
                   1014:        if (!(cl_reg->cl_ier & 0x08)) {
                   1015:                ier_old = cl_reg->cl_ier;
                   1016:                cl_reg->cl_ier  = 0x08;
                   1017:        }
                   1018:        while (got_char == 0) {
                   1019:                val = cl_reg->cl_rir;
                   1020:                /* if no receive interrupt pending wait */
                   1021:                if (!(val & 0x80)) {
                   1022:                        continue;
                   1023:                }
                   1024:                /* XXX do we need to suck the entire FIFO contents? */
                   1025:                reoir = pcc2_base->pcc2_sccrxiack; /* receive PIACK */
                   1026:                licr = cl_reg->cl_licr;
                   1027:                if (((licr >> 2) & 0x3) == 0) {
                   1028:                        /* is the interrupt for us (port 0) */
                   1029:                        /* the character is for us yea. */
                   1030:                        isrl = cl_reg->cl_risrl;
                   1031: #if 0
                   1032:                        if (isrl & 0x01) {
                   1033:                                status = BREAK;
                   1034:                        }
                   1035:                        if (isrl & 0x02) {
                   1036:                                status = FRAME;
                   1037:                        }
                   1038:                        if (isrl & 0x04) {
                   1039:                                status = PARITY;
                   1040:                        }
                   1041:                        if (isrl & 0x08) {
                   1042:                                status = OVERFLOW;
                   1043:                        }
                   1044:                        /* we do not have special characters ;-) */
                   1045: #endif
                   1046:                        fifo_cnt = cl_reg->cl_rfoc;
                   1047:                        data = cl_reg->cl_rdr;
                   1048:                        if (ier_old != 0xff) {
                   1049:                                cl_reg->cl_ier  = ier_old;
                   1050:                        }
                   1051:                        got_char = 1;
                   1052:                        cl_reg->cl_teoir = 0x00;
                   1053:                } else {
                   1054:                        data = cl_reg->cl_rdr;
                   1055:                        cl_reg->cl_teoir = 0x00;
                   1056:                }
                   1057:
                   1058:        }
                   1059:
                   1060:        return data;
                   1061: }
                   1062:
                   1063: void
                   1064: clcnputc(dev, c)
                   1065:        dev_t dev;
                   1066:        u_char c;
                   1067: {
                   1068:        clputc(0, 0, c);
                   1069: }
                   1070:
                   1071: void
                   1072: clcnpollc(dev, on)
                   1073:        dev_t dev;
                   1074:        int on;
                   1075: {
                   1076:        if (1 == on) {
                   1077:                /* enable polling */
                   1078:        } else {
                   1079:                /* disable polling */
                   1080:        }
                   1081:        return;
                   1082: }
                   1083:
                   1084: void
                   1085: clputc(sc, unit, c)
                   1086:        struct clsoftc *sc;
                   1087:        int unit;
                   1088:        u_char c;
                   1089: {
                   1090:        int s;
                   1091:        u_char schar;
                   1092:        u_char oldchannel;
                   1093:        struct clreg *cl_reg;
                   1094:        if (0 == sc) {
                   1095:                /* output on console */
                   1096:                cl_reg = cl_cons.cl_vaddr;
                   1097:        } else {
                   1098:                cl_reg = sc->cl_reg;
                   1099:        }
                   1100: #ifdef NEW_CLCD_STRUCT
                   1101:        /* should we disable, flush and all that goo? */
                   1102:        cl->car = unit;
                   1103:        schar = cl->schr3;
                   1104:        cl->schr3 = c;
                   1105:        cl->stcr = 0x08 | 0x03; /* send special char, char 3 */
                   1106:        while (0 != cl->stcr) {
                   1107:                /* wait until cl notices the command
                   1108:                 * otherwise it may not notice the character
                   1109:                 * if we send characters too fast.
                   1110:                 */
                   1111:        }
                   1112:        cl->schr3 = schar;
                   1113: #else
                   1114: if (unit == 0) {
                   1115:        s = splhigh();
                   1116:        oldchannel = cl_reg->cl_car;
                   1117:        cl_reg->cl_car = unit;
                   1118:        schar = cl_reg->cl_schr3;
                   1119:        cl_reg->cl_schr3 = c;
                   1120:        cl_reg->cl_stcr = 0x08 | 0x03; /* send special char, char 3 */
                   1121:        while (0 != cl_reg->cl_stcr) {
                   1122:                /* wait until cl notices the command
                   1123:                 * otherwise it may not notice the character
                   1124:                 * if we send characters too fast.
                   1125:                 */
                   1126:        }
                   1127:        DELAY(5);
                   1128:        cl_reg->cl_schr3 = schar;
                   1129:        cl_reg->cl_car = oldchannel;
                   1130:        splx(s);
                   1131: } else {
                   1132:        s = splhigh();
                   1133:        oldchannel = cl_reg->cl_car;
                   1134:        cl_reg->cl_car = unit;
                   1135:        if (cl_reg->cl_tftc > 0) {
                   1136:                cl_reg->cl_tdr = c;
                   1137:        }
                   1138:        cl_reg->cl_car = oldchannel;
                   1139:        splx(s);
                   1140: }
                   1141: #endif
                   1142:        return;
                   1143: }
                   1144:
                   1145: u_char
                   1146: clgetc(sc, channel)
                   1147:        struct clsoftc *sc;
                   1148:        int *channel;
                   1149: {
                   1150:        struct clreg *cl_reg;
                   1151:        volatile struct pcctworeg *pcc2_base;
                   1152:        u_char val, reoir, licr, isrl, fifo_cnt, data;
                   1153:        if (sc == NULL) {
                   1154:                cl_reg = cl_cons.cl_vaddr;
                   1155:                pcc2_base = cl_cons.pcctwoaddr;
                   1156:        } else {
                   1157:                cl_reg = sc->cl_reg;
                   1158:                pcc2_base = sys_pcc2;
                   1159:        }
                   1160:        val = cl_reg->cl_rir;
                   1161:        /* if no receive interrupt pending wait */
                   1162:        if (!(val & 0x80)) {
                   1163:                return 0;
                   1164:        }
                   1165:        /* XXX do we need to suck the entire FIFO contents? */
                   1166:        reoir = pcc2_base->pcc2_sccrxiack; /* receive PIACK */
                   1167:        licr = cl_reg->cl_licr;
                   1168:        *channel = (licr >> 2) & 0x3;
                   1169:        /* is the interrupt for us (port 0) */
                   1170:        /* the character is for us yea. */
                   1171:        isrl = cl_reg->cl_risrl;
                   1172: #if 0
                   1173:        if (isrl & 0x01) {
                   1174:                status = BREAK;
                   1175:        }
                   1176:        if (isrl & 0x02) {
                   1177:                status = FRAME;
                   1178:        }
                   1179:        if (isrl & 0x04) {
                   1180:                status = PARITY;
                   1181:        }
                   1182:        if (isrl & 0x08) {
                   1183:                status = OVERFLOW;
                   1184:        }
                   1185:        /* we do not have special characters ;-) */
                   1186: #endif
                   1187:        fifo_cnt = cl_reg->cl_rfoc;
                   1188:        if (fifo_cnt > 0) {
                   1189:                data = cl_reg->cl_rdr;
                   1190:                cl_reg->cl_teoir = 0x00;
                   1191:        } else {
                   1192:                data = 0;
                   1193:                cl_reg->cl_teoir = 0x08;
                   1194:        }
                   1195:        return data;
                   1196: }
                   1197: int
                   1198: clccparam(sc, par, channel)
                   1199:        struct clsoftc *sc;
                   1200:        struct termios *par;
                   1201:        int channel;
                   1202: {
                   1203:        u_int divisor, clk, clen;
                   1204:        int s, imask, ints;
                   1205:
                   1206:        s = splcl();
                   1207:        sc->cl_reg->cl_car = channel;
                   1208:        if (par->c_ospeed == 0) {
                   1209:                /* dont kill the console */
                   1210:                if(sc->sc_cl[channel].cl_consio == 0) {
                   1211:                        /* disconnect, drop RTS DTR stop receiver */
                   1212:                        sc->cl_reg->cl_msvr_rts = 0x00;
                   1213:                        sc->cl_reg->cl_msvr_dtr = 0x00;
                   1214:                        sc->cl_reg->cl_ccr = 0x05;
                   1215:                }
                   1216:                splx(s);
                   1217:                return (0xff);
                   1218:        }
                   1219:
                   1220:        sc->cl_reg->cl_msvr_rts = 0x03;
                   1221:        sc->cl_reg->cl_msvr_dtr = 0x03;
                   1222:
                   1223:        divisor = cl_clkdiv(par->c_ospeed);
                   1224:        clk     = cl_clknum(par->c_ospeed);
                   1225:        sc->cl_reg->cl_tbpr = divisor;
                   1226:        sc->cl_reg->cl_tcor = clk << 5;
                   1227:        divisor = cl_clkdiv(par->c_ispeed);
                   1228:        clk     = cl_clknum(par->c_ispeed);
                   1229:        sc->cl_reg->cl_rbpr = divisor;
                   1230:        sc->cl_reg->cl_rcor = clk;
                   1231:        sc->cl_reg->cl_rtprl = cl_clkrxtimeout(par->c_ispeed);
                   1232:        sc->cl_reg->cl_rtprh = 0x00;
                   1233:
                   1234:        switch (par->c_cflag & CSIZE) {
                   1235:        case CS5:
                   1236:                clen = 4; /* this is the mask for the chip. */
                   1237:                imask = 0x1F;
                   1238:                break;
                   1239:        case CS6:
                   1240:                clen = 5;
                   1241:                imask = 0x3F;
                   1242:                break;
                   1243:        case CS7:
                   1244:                clen = 6;
                   1245:                imask = 0x7F;
                   1246:                break;
                   1247:        default:
                   1248:                clen = 7;
                   1249:                imask = 0xFF;
                   1250:        }
                   1251:        sc->cl_reg->cl_cor3 = par->c_cflag & PARENB ? 4 : 2;
                   1252:
                   1253:        {
                   1254:                u_char cor1;
                   1255:                if (par->c_cflag & PARENB) {
                   1256:                        if (par->c_cflag & PARODD) {
                   1257:                                cor1 = 0xE0 | clen ; /* odd */
                   1258:                        } else {
                   1259:                                cor1 = 0x40 | clen ; /* even */
                   1260:                        }
                   1261:                } else {
                   1262:                        cor1 = 0x10 | clen; /* ignore parity */
                   1263:                }
                   1264:                if (sc->cl_reg->cl_cor1 != cor1) {
                   1265:                        sc->cl_reg->cl_cor1 = cor1;
                   1266:                        sc->cl_reg->cl_ccr = 0x20;
                   1267:                        while (sc->cl_reg->cl_ccr != 0) {
                   1268:                        }
                   1269:                }
                   1270:        }
                   1271:
                   1272:        if (sc->sc_cl[channel].cl_consio == 0 && (par->c_cflag & CREAD) == 0)
                   1273:                sc->cl_reg->cl_ccr = 0x08;
                   1274:        else
                   1275:                sc->cl_reg->cl_ccr = 0x0a;
                   1276:        while (sc->cl_reg->cl_ccr != 0) {
                   1277:        }
                   1278:        ints = 0;
                   1279: #define SCC_DSR 0x80
                   1280: #define SCC_DCD 0x40
                   1281: #define SCC_CTS 0x20
                   1282:        if ((par->c_cflag & CLOCAL) == 0) {
                   1283:                ints |= SCC_DCD;
                   1284:        }
                   1285:        if ((par->c_cflag & CCTS_OFLOW) != 0) {
                   1286:                ints |= SCC_CTS;
                   1287:        }
                   1288:        if ((par->c_cflag & CRTSCTS) != 0) {
                   1289:                ints |= SCC_CTS;
                   1290:        }
                   1291: #ifdef DONT_LET_HARDWARE
                   1292:        if ((par->c_cflag & CCTS_IFLOW) != 0) {
                   1293:                ints |= SCC_DSR;
                   1294:        }
                   1295: #endif
                   1296:        sc->cl_reg->cl_cor4 = ints | CL_FIFO_CNT;
                   1297:        sc->cl_reg->cl_cor5 = ints | CL_FIFO_CNT;
                   1298:
                   1299:        return imask;
                   1300: }
                   1301: static int clknum = 0;
                   1302: u_char
                   1303: cl_clkdiv(speed)
                   1304:        int speed;
                   1305: {
                   1306:        int i = 0;
                   1307:        if (cl_clocks[clknum].speed == speed) {
                   1308:                return cl_clocks[clknum].divisor;
                   1309:        }
                   1310:        for  (i = 0; cl_clocks[i].speed != 0; i++) {
                   1311:                if (cl_clocks[i].speed == speed) {
                   1312:                        clknum = i;
                   1313:                        return cl_clocks[clknum].divisor;
                   1314:                }
                   1315:        }
                   1316:        /* return some sane value if unknown speed */
                   1317:        return cl_clocks[4].divisor;
                   1318: }
                   1319: u_char
                   1320: cl_clknum(speed)
                   1321:        int speed;
                   1322: {
                   1323:        int found = 0;
                   1324:        int i = 0;
                   1325:        if (cl_clocks[clknum].speed == speed) {
                   1326:                return cl_clocks[clknum].clock;
                   1327:        }
                   1328:        for  (i = 0; found != 0 && cl_clocks[i].speed != 0; i++) {
                   1329:                if (cl_clocks[clknum].speed == speed) {
                   1330:                        clknum = i;
                   1331:                        return cl_clocks[clknum].clock;
                   1332:                }
                   1333:        }
                   1334:        /* return some sane value if unknown speed */
                   1335:        return cl_clocks[4].clock;
                   1336: }
                   1337: u_char
                   1338: cl_clkrxtimeout(speed)
                   1339:        int speed;
                   1340: {
                   1341:        int i = 0;
                   1342:        if (cl_clocks[clknum].speed == speed) {
                   1343:                return cl_clocks[clknum].rx_timeout;
                   1344:        }
                   1345:        for  (i = 0; cl_clocks[i].speed != 0; i++) {
                   1346:                if (cl_clocks[i].speed == speed) {
                   1347:                        clknum = i;
                   1348:                        return cl_clocks[clknum].rx_timeout;
                   1349:                }
                   1350:        }
                   1351:        /* return some sane value if unknown speed */
                   1352:        return cl_clocks[4].rx_timeout;
                   1353: }
                   1354: void
                   1355: cl_unblock(tp)
                   1356:        struct tty *tp;
                   1357: {
                   1358:        tp->t_state &= ~TS_FLUSH;
                   1359:        if (tp->t_outq.c_cc != 0)
                   1360:                clstart(tp);
                   1361: }
                   1362: void
                   1363: clstart(tp)
                   1364:        struct tty *tp;
                   1365: {
                   1366:        dev_t dev;
                   1367: #if 0
                   1368:        u_char cbuf;
                   1369:        int cnt;
                   1370: #endif
                   1371:        struct clsoftc *sc;
                   1372:        int channel, unit, s;
                   1373:
                   1374:        dev = tp->t_dev;
                   1375:        channel = CL_CHANNEL(dev);
                   1376: /* hack to test output on non console only */
                   1377: #if 0
                   1378:        if (channel == 0) {
                   1379:                cloutput(tp);
                   1380:                return;
                   1381:        }
                   1382: #endif
                   1383:        unit = CL_UNIT(dev);
                   1384:        if (unit >= cl_cd.cd_ndevs ||
                   1385:                (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
                   1386:                return;
                   1387:        }
                   1388:
                   1389:        if ((tp->t_state & TS_ISOPEN) == 0)
                   1390:                return;
                   1391:
                   1392:        s = splcl();
                   1393: #if 0
                   1394:        if (sc->sc_cl[channel].transmitting == 1) {
                   1395:                /* i'm busy, go away, I will get to it later. */
                   1396:                splx(s);
                   1397:                return;
                   1398:        }
                   1399:        cnt = q_to_b(&tp->t_outq, &cbuf, 1);
                   1400:        if ( cnt != 0 ) {
                   1401:                sc->sc_cl[channel].transmitting = 1;
                   1402:                sc->cl_reg->cl_car = channel;
                   1403:                sc->cl_reg->cl_tdr = cbuf;
                   1404:        } else {
                   1405:                sc->sc_cl[channel].transmitting = 0;
                   1406:        }
                   1407: #else
                   1408:        if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP | TS_FLUSH)) == 0)
                   1409:        {
                   1410:                tp->t_state |= TS_BUSY;
                   1411:                sc->cl_reg->cl_car = channel;
                   1412:                sc->cl_reg->cl_ier = sc->cl_reg->cl_ier | 0x3;
                   1413:        }
                   1414: #endif
                   1415:        splx(s);
                   1416:        return;
                   1417: }
                   1418: int
                   1419: cl_mintr(arg)
                   1420:        void *arg;
                   1421: {
                   1422:        struct clsoftc *sc = (struct clsoftc *)arg;
                   1423:        u_char mir, misr, msvr;
                   1424:        int channel;
                   1425:        if(((mir = sc->cl_reg->cl_mir) & 0x40) == 0x0) {
                   1426:                /* only if intr is not shared? */
                   1427:                log(LOG_WARNING, "cl_mintr extra intr\n");
                   1428:                return 0;
                   1429:        }
                   1430:
                   1431:        channel = mir & 0x03;
                   1432:        misr = sc->cl_reg->cl_misr;
                   1433:        msvr = sc->cl_reg->cl_msvr_rts;
                   1434:        if (misr & 0x01) {
                   1435:                /* timers are not currently used?? */
                   1436:                log(LOG_WARNING, "cl_mintr: channel %x timer 1 unexpected\n",channel);
                   1437:        }
                   1438:        if (misr & 0x02) {
                   1439:                /* timers are not currently used?? */
                   1440:                log(LOG_WARNING, "cl_mintr: channel %x timer 2 unexpected\n",channel);
                   1441:        }
                   1442:        if (misr & 0x20) {
                   1443:                struct tty *tp = sc->sc_cl[channel].tty;
                   1444: #ifdef VERBOSE_LOG_MESSAGES
                   1445:                log(LOG_WARNING, "cl_mintr: channel %x cts %x\n",channel,
                   1446:                ((msvr & 0x20) != 0x0)
                   1447:                );
                   1448: #endif
                   1449:                if (msvr & 0x20) {
                   1450:                        cl_unblock(tp);
                   1451:                }
                   1452:        }
                   1453:        if (misr & 0x40) {
                   1454:                struct tty *tp = sc->sc_cl[channel].tty;
                   1455: #ifdef VERBOSE_LOG_MESSAGES
                   1456:                log(LOG_WARNING, "cl_mintr: channel %x cd %x\n",channel,
                   1457:                ((msvr & 0x40) != 0x0)
                   1458:                );
                   1459: #endif
                   1460:                ttymodem(tp, ((msvr & 0x40) != 0x0) );
                   1461:        }
                   1462:        if (misr & 0x80) {
                   1463: #ifdef VERBOSE_LOG_MESSAGES
                   1464:                log(LOG_WARNING, "cl_mintr: channel %x dsr %x\n",channel,
                   1465:                ((msvr & 0x80) != 0x0)
                   1466:                );
                   1467: #endif
                   1468:        }
                   1469:        sc->cl_reg->cl_meoir = 0x00;
                   1470:        return 1;
                   1471: }
                   1472:
                   1473: int
                   1474: cl_txintr(arg)
                   1475:        void *arg;
                   1476: {
                   1477:        struct clsoftc *sc = (struct clsoftc *)arg;
                   1478:        static int empty = 0;
                   1479:        u_char tir, cmr, teoir;
                   1480:        u_char max;
                   1481:        int channel;
                   1482:        struct tty *tp;
                   1483:        int cnt;
                   1484:        u_char buffer[CL_FIFO_MAX +1];
                   1485:        u_char *tptr;
                   1486:        if(((tir = sc->cl_reg->cl_tir) & 0x40) == 0x0) {
                   1487:                /* only if intr is not shared ??? */
                   1488:                log(LOG_WARNING, "cl_txintr extra intr\n");
                   1489:                return 0;
                   1490:        }
                   1491:
                   1492:        channel = tir & 0x03;
                   1493:        cmr     = sc->cl_reg->cl_cmr;
                   1494:
                   1495:        sc->sc_cl[channel].txcnt ++;
                   1496:
                   1497:        tp = sc->sc_cl[channel].tty;
                   1498:        if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) {
                   1499:                sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~0x3;
                   1500:                sc->cl_reg->cl_teoir = 0x08;
                   1501:                return 1;
                   1502:        }
                   1503:        switch (cmr & CL_TXMASK) {
                   1504:        case CL_TXDMAINT:
                   1505:                {
                   1506:                        u_char dmabsts;
                   1507:                        int nbuf, busy, resid;
                   1508:                        void *pbuffer;
                   1509:                        dmabsts = sc->cl_reg->cl_dmabsts;
                   1510:                log(LOG_WARNING, "cl_txintr: DMAMODE channel %x dmabsts %x\n",
                   1511:                        channel, dmabsts);
                   1512:                        nbuf = ((dmabsts & 0x8) >> 3) & 0x1;
                   1513:                        busy = ((dmabsts & 0x4) >> 2) & 0x1;
                   1514:
                   1515:                        do {
                   1516:                                pbuffer = sc->sc_cl[channel].tx[nbuf];
                   1517:                                resid = tp->t_outq.c_cc;
                   1518:                                cnt = min (CL_BUFSIZE,resid);
                   1519:                log(LOG_WARNING, "cl_txintr: resid %x cnt %x pbuf %p\n",
                   1520:                        resid, cnt, pbuffer);
                   1521:                                if (cnt != 0) {
                   1522:                                        cnt = q_to_b(&tp->t_outq, pbuffer, cnt);
                   1523:                                        resid -= cnt;
                   1524:                                        if (nbuf == 0) {
                   1525:                                                sc->cl_reg->cl_atbadru =
                   1526:                                                        ((u_long) sc->sc_cl[channel].txp[nbuf]) >> 16;
                   1527:                                                sc->cl_reg->cl_atbadrl =
                   1528:                                                        ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff;
                   1529:                                                sc->cl_reg->cl_atbcnt = cnt;
                   1530:                                                sc->cl_reg->cl_atbsts = 0x43;
                   1531:                                        } else {
                   1532:                                                sc->cl_reg->cl_btbadru =
                   1533:                                                        ((u_long) sc->sc_cl[channel].txp[nbuf]) >> 16;
                   1534:                                                sc->cl_reg->cl_btbadrl =
                   1535:                                                        ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff;
                   1536:                                                sc->cl_reg->cl_btbcnt = cnt;
                   1537:                                                sc->cl_reg->cl_btbsts = 0x43;
                   1538:                                        }
                   1539:                                teoir = 0x08;
                   1540:                                } else {
                   1541:                                        teoir = 0x08;
                   1542:                                        if (tp->t_state & TS_BUSY) {
                   1543:                                                tp->t_state &= ~(TS_BUSY | TS_FLUSH);
                   1544:                                                if (tp->t_state & TS_ASLEEP) {
                   1545:                                                        tp->t_state &= ~TS_ASLEEP;
                   1546:                                                        wakeup((caddr_t) &tp->t_outq);
                   1547:                                                }
                   1548:                                                selwakeup(&tp->t_wsel);
                   1549:                                        }
                   1550:                                        sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~0x3;
                   1551:                                }
                   1552:                                nbuf = ~nbuf & 0x1;
                   1553:                                busy--;
                   1554:                        } while (resid != 0 && busy != -1);/* if not busy do other buffer */
                   1555:                log(LOG_WARNING, "cl_txintr: done\n");
                   1556:                }
                   1557:                break;
                   1558:        case CL_TXINTR:
                   1559:                max = sc->cl_reg->cl_tftc;
                   1560:                cnt = min ((int)max,tp->t_outq.c_cc);
                   1561:                if (cnt != 0) {
                   1562:                        cnt = q_to_b(&tp->t_outq, buffer, cnt);
                   1563:                        empty = 0;
                   1564:                        for (tptr = buffer; tptr < &buffer[cnt]; tptr++) {
                   1565:                                sc->cl_reg->cl_tdr = *tptr;
                   1566:                        }
                   1567:                        teoir = 0x00;
                   1568:                } else {
                   1569:                        if (empty > 5 && ((empty % 20000 )== 0)) {
                   1570:                        log(LOG_WARNING, "cl_txintr to many empty intr %d channel %d\n",
                   1571:                                empty, channel);
                   1572:                        }
                   1573:                        empty++;
                   1574:                        teoir = 0x08;
                   1575:                        if (tp->t_state & TS_BUSY) {
                   1576:                                tp->t_state &= ~(TS_BUSY | TS_FLUSH);
                   1577:                                if (tp->t_state & TS_ASLEEP) {
                   1578:                                        tp->t_state &= ~TS_ASLEEP;
                   1579:                                        wakeup((caddr_t) &tp->t_outq);
                   1580:                                }
                   1581:                                selwakeup(&tp->t_wsel);
                   1582:                        }
                   1583:                        sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~0x3;
                   1584:                }
                   1585:                break;
                   1586:        default:
                   1587:                log(LOG_WARNING, "cl_txintr unknown mode %x\n", cmr);
                   1588:                /* we probably will go to hell quickly now */
                   1589:                teoir = 0x08;
                   1590:        }
                   1591:        sc->cl_reg->cl_teoir = teoir;
                   1592:        return 1;
                   1593: }
                   1594:
                   1595: int
                   1596: cl_rxintr(arg)
                   1597:        void *arg;
                   1598: {
                   1599:        struct clsoftc *sc = (struct clsoftc *)arg;
                   1600:        u_char rir, channel, cmr, risrl;
                   1601:        u_char fifocnt;
                   1602:        struct tty *tp;
                   1603:        int i;
                   1604:        u_char reoir;
                   1605:        u_char buffer[CL_FIFO_MAX +1];
                   1606: #ifdef DDB
                   1607:        int wantddb = 0;
                   1608: #endif
                   1609:
                   1610:        rir = sc->cl_reg->cl_rir;
                   1611:        if((rir & 0x40) == 0x0) {
                   1612:                /* only if intr is not shared ??? */
                   1613:                log(LOG_WARNING, "cl_rxintr extra intr\n");
                   1614:                return 0;
                   1615:        }
                   1616:
                   1617:        channel = rir & 0x3;
                   1618:        cmr = sc->cl_reg->cl_cmr;
                   1619:        reoir = 0x08;
                   1620:
                   1621:        sc->sc_cl[channel].rxcnt ++;
                   1622:        risrl = sc->cl_reg->cl_risrl;
                   1623:        if (risrl & 0x80) {
                   1624:                /* timeout, no characters */
                   1625:                reoir = 0x08;
                   1626:        } else
                   1627:        /* We don't need no sinkin special characters */
                   1628:        if (risrl & 0x08) {
                   1629:                cl_overflow (sc, channel, &sc->sc_fotime, "fifo");
                   1630:                reoir = 0x08;
                   1631:        } else
                   1632:        if (risrl & 0x04) {
                   1633:                cl_parity(sc, channel);
                   1634:                reoir = 0x08;
                   1635:        } else
                   1636:        if (risrl & 0x02) {
                   1637:                cl_frame(sc, channel);
                   1638:                reoir = 0x08;
                   1639:        } else
                   1640:        if (risrl & 0x01) {
                   1641: #ifdef DDB
                   1642:                if (sc->sc_cl[channel].cl_consio)
                   1643:                        wantddb = db_console;
                   1644: #endif
                   1645:                cl_break(sc, channel);
                   1646:                reoir = 0x08;
                   1647:        }
                   1648:
                   1649:        switch (cmr & CL_RXMASK) {
                   1650:        case CL_RXDMAINT:
                   1651:                {
                   1652:                        int nbuf;
                   1653:                        u_short cnt;
                   1654:                        int bufcomplete;
                   1655:                        u_char status, dmabsts;
                   1656:                        u_char risrh = sc->cl_reg->cl_risrh;
                   1657:                        dmabsts = sc->cl_reg->cl_dmabsts;
                   1658: #ifdef DMA_DEBUG
                   1659: log(LOG_WARNING, "cl_txintr: DMAMODE channel %x dmabsts %x risrl %x risrh %x\n",
                   1660:        channel, dmabsts, risrl, risrh);
                   1661: #endif
                   1662:                        nbuf = (risrh & 0x08) ? 1 : 0;
                   1663:                        bufcomplete = (risrh & 0x20) ? 1 : 0;
                   1664:                        if (nbuf == 0) {
                   1665:                                cnt  = sc->cl_reg->cl_arbcnt;
                   1666:                                status =  sc->cl_reg->cl_arbsts;
                   1667:                        } else {
                   1668:                                cnt  = sc->cl_reg->cl_brbcnt;
                   1669:                                status =  sc->cl_reg->cl_brbsts;
                   1670:                        }
                   1671: #ifdef DMA_DEBUG
                   1672: log(LOG_WARNING, "cl_rxintr: 1channel %x buf %x cnt %x status %x\n",
                   1673: channel, nbuf, cnt, status);
                   1674: #endif
                   1675: #ifdef USE_BUFFER
                   1676:                        cl_appendbufn(sc, channel,
                   1677:                                sc->sc_cl[channel].rx[nbuf], cnt);
                   1678: #else
                   1679:                        {
                   1680:                                int i;
                   1681:                                u_char *pbuf;
                   1682:                                tp = sc->sc_cl[channel].tty;
                   1683:                                pbuf = sc->sc_cl[channel].rx[nbuf];
                   1684:                        /* this should be done at off level */
                   1685: {
                   1686:        u_short rcbadru, rcbadrl;
                   1687:        u_char arbsts, brbsts;
                   1688:        u_char *pbufs, *pbufe;
                   1689:        rcbadru = sc->cl_reg->cl_rcbadru;
                   1690:        rcbadrl = sc->cl_reg->cl_rcbadrl;
                   1691:        arbsts =  sc->cl_reg->cl_arbsts;
                   1692:        brbsts =  sc->cl_reg->cl_brbsts;
                   1693:        pbufs = sc->sc_cl[channel].rxp[nbuf];
                   1694:        pbufe = (u_char *)(((u_long)rcbadru << 16) | (u_long)rcbadrl);
                   1695:        cnt = pbufe - pbufs;
                   1696: #ifdef DMA_DEBUG
                   1697:        log(LOG_WARNING, "cl_rxintr: rcbadru %x rcbadrl %x arbsts %x brbsts %x cnt %x\n",
                   1698:        rcbadru, rcbadrl, arbsts, brbsts, cnt);
                   1699: #endif
                   1700: #ifdef DMA_DEBUG1
                   1701:        log(LOG_WARNING, "cl_rxintr: buf %x cnt %x\n",
                   1702:        nbuf, cnt);
                   1703: #endif
                   1704: }
                   1705:                                reoir = 0x0 | (bufcomplete) ? 0 : 0xd0;
                   1706:                                sc->cl_reg->cl_reoir = reoir;
                   1707: #ifdef DMA_DEBUG
                   1708: log(LOG_WARNING, "cl_rxintr: reoir %x\n", reoir);
                   1709: #endif
                   1710:                                delay(10); /* give the chip a moment */
                   1711: #ifdef DMA_DEBUG
                   1712: log(LOG_WARNING, "cl_rxintr: 2channel %x buf %x cnt %x status %x\n",
                   1713: channel, nbuf, cnt, status);
                   1714: #endif
                   1715:                                for (i = 0; i < cnt; i++) {
                   1716:                                        u_char c;
                   1717:                                        c = pbuf[i];
                   1718:                                        (*linesw[tp->t_line].l_rint)(c,tp);
                   1719:                                }
                   1720:                        /* this should be done at off level */
                   1721:                                if (nbuf == 0) {
                   1722:                                        sc->cl_reg->cl_arbcnt = CL_BUFSIZE;
                   1723:                                        sc->cl_reg->cl_arbsts = 0x01;
                   1724:                                } else {
                   1725:                                        sc->cl_reg->cl_brbcnt = CL_BUFSIZE;
                   1726:                                        sc->cl_reg->cl_brbsts = 0x01;
                   1727:                                }
                   1728:                        }
                   1729: #endif
                   1730:                }
                   1731:                sc->cl_reg->cl_reoir = reoir;
                   1732:                break;
                   1733:        case CL_RXINTR:
                   1734:                fifocnt = sc->cl_reg->cl_rfoc;
                   1735:                tp = sc->sc_cl[channel].tty;
                   1736:                for (i = 0; i < fifocnt; i++) {
                   1737:                        buffer[i] = sc->cl_reg->cl_rdr;
                   1738:                }
                   1739:                if (NULL == tp) {
                   1740:                        /* if the channel is not configured,
                   1741:                         * dont send characters upstream.
                   1742:                         * also fix problem with NULL dereference
                   1743:                         */
                   1744:                        reoir = 0x00;
                   1745:                        break;
                   1746:                }
                   1747:
                   1748:                sc->cl_reg->cl_reoir = reoir;
                   1749: #ifdef USE_BUFFER
                   1750:                cl_appendbufn(sc, channel, buffer, fifocnt);
                   1751: #else
                   1752:                for (i = 0; i < fifocnt; i++) {
                   1753:                        u_char c;
                   1754:                        c = buffer[i];
                   1755:                        /* does any restricitions exist on spl
                   1756:                         * for this call
                   1757:                         */
                   1758:                        (*linesw[tp->t_line].l_rint)(c,tp);
                   1759:                        reoir = 0x00;
                   1760:                }
                   1761: #endif
                   1762:                break;
                   1763:        default:
                   1764:                log(LOG_WARNING, "cl_rxintr unknown mode %x\n", cmr);
                   1765:                /* we probably will go to hell quickly now */
                   1766:                reoir = 0x08;
                   1767:                sc->cl_reg->cl_reoir = reoir;
                   1768:        }
                   1769: #ifdef DDB
                   1770:        if (wantddb != 0)
                   1771:                Debugger();
                   1772: #endif
                   1773:        return 1;
                   1774: }
                   1775:
                   1776: void
                   1777: cl_overflow (sc, channel, ptime, msg)
                   1778: struct clsoftc *sc;
                   1779: int channel;
                   1780: time_t *ptime;
                   1781: u_char *msg;
                   1782: {
                   1783: /*
                   1784:        if (*ptime != time.tv_sec) {
                   1785: */
                   1786:        {
                   1787: /*
                   1788:                *ptime = time.tv_sec;
                   1789: */
                   1790:                log(LOG_WARNING, "%s%d[%d]: %s overrun\n", cl_cd.cd_name,
                   1791:                        0 /* fix */, channel, msg);
                   1792:        }
                   1793:        return;
                   1794: }
                   1795: void
                   1796: cl_parity (sc, channel)
                   1797:        struct clsoftc *sc;
                   1798:        int channel;
                   1799: {
                   1800: #ifdef VERBOSE_LOG_MESSAGES
                   1801:        log(LOG_WARNING, "%s%d[%d]: parity error\n", cl_cd.cd_name, 0, channel);
                   1802: #endif
                   1803:        return;
                   1804: }
                   1805: void
                   1806: cl_frame (sc, channel)
                   1807:        struct clsoftc *sc;
                   1808:        int channel;
                   1809: {
                   1810: #ifdef VERBOSE_LOG_MESSAGES
                   1811:        log(LOG_WARNING, "%s%d[%d]: frame error\n", cl_cd.cd_name, 0, channel);
                   1812: #endif
                   1813:        return;
                   1814: }
                   1815: void
                   1816: cl_break (sc, channel)
                   1817:        struct clsoftc *sc;
                   1818:        int channel;
                   1819: {
                   1820: #ifdef VERBOSE_LOG_MESSAGES
                   1821:        log(LOG_WARNING, "%s%d[%d]: break detected\n", cl_cd.cd_name, 0, channel);
                   1822: #endif
                   1823:        return;
                   1824: }
                   1825:
                   1826: void
                   1827: cl_dumpport(channel)
                   1828:        int channel;
                   1829: {
                   1830:        u_char  livr, cmr, cor1, cor2, cor3, cor4, cor5, cor6, cor7,
                   1831:                schr1, schr2, schr3, schr4, scrl, scrh, lnxt,
                   1832:                rbpr, rcor, tbpr, tcor, rpilr, rir, tpr, ier, ccr,
                   1833:                dmabsts, arbsts, brbsts, atbsts, btbsts,
                   1834:                csr, rts, dtr, rtprl, rtprh;
                   1835:        volatile void * parbadru, *parbadrl,  *parbsts, *parbcnt;
                   1836:        u_short rcbadru, rcbadrl, arbadru, arbadrl, arbcnt,
                   1837:                brbadru, brbadrl, brbcnt;
                   1838:        u_short tcbadru, tcbadrl, atbadru, atbadrl, atbcnt,
                   1839:                btbadru, btbadrl, btbcnt;
                   1840:        struct clsoftc *sc;
                   1841:
                   1842:        struct clreg *cl_reg;
                   1843:        int s;
                   1844:
                   1845:        cl_reg = cl_cons.cl_vaddr;
                   1846:
                   1847:        sc = (struct clsoftc *) cl_cd.cd_devs[0];
                   1848:
                   1849:        s = splcl();
                   1850:        cl_reg->cl_car  = (u_char) channel;
                   1851:        livr = cl_reg->cl_livr;
                   1852:        cmr = cl_reg->cl_cmr;
                   1853:        cor1 = cl_reg->cl_cor1;
                   1854:        cor2 = cl_reg->cl_cor2;
                   1855:        cor3 = cl_reg->cl_cor3;
                   1856:        cor4 = cl_reg->cl_cor4;
                   1857:        cor5 = cl_reg->cl_cor5;
                   1858:        cor6 = cl_reg->cl_cor6;
                   1859:        cor7 = cl_reg->cl_cor7;
                   1860:        schr1 = cl_reg->cl_schr1;
                   1861:        schr2 = cl_reg->cl_schr2;
                   1862:        schr3 = cl_reg->cl_schr3;
                   1863:        schr4 = cl_reg->cl_schr4;
                   1864:        scrl = cl_reg->cl_scrl;
                   1865:        scrh = cl_reg->cl_scrh;
                   1866:        lnxt = cl_reg->cl_lnxt;
                   1867:        rbpr = cl_reg->cl_rbpr;
                   1868:        rcor = cl_reg->cl_rcor;
                   1869:        tbpr = cl_reg->cl_tbpr;
                   1870:        rpilr = cl_reg->cl_rpilr;
                   1871:        rir = cl_reg->cl_rir;
                   1872:        ier = cl_reg->cl_ier;
                   1873:        ccr = cl_reg->cl_ccr;
                   1874:        tcor = cl_reg->cl_tcor;
                   1875:        csr = cl_reg->cl_csr;
                   1876:        tpr = cl_reg->cl_tpr;
                   1877:        rts = cl_reg->cl_msvr_rts;
                   1878:        dtr = cl_reg->cl_msvr_dtr;
                   1879:        rtprl = cl_reg->cl_rtprl;
                   1880:        rtprh = cl_reg->cl_rtprh;
                   1881:        dmabsts = cl_reg->cl_dmabsts;
                   1882:        tcbadru = cl_reg->cl_tcbadru;
                   1883:        tcbadrl = cl_reg->cl_tcbadrl;
                   1884:        rcbadru = cl_reg->cl_rcbadru;
                   1885:        rcbadrl = cl_reg->cl_rcbadrl;
                   1886:
                   1887:        parbadru = &(cl_reg->cl_arbadru);
                   1888:        parbadrl = &(cl_reg->cl_arbadrl);
                   1889:        parbcnt  = &(cl_reg->cl_arbcnt);
                   1890:        parbsts  = &(cl_reg->cl_arbsts);
                   1891:
                   1892:        arbadru = cl_reg->cl_arbadru;
                   1893:        arbadrl = cl_reg->cl_arbadrl;
                   1894:        arbcnt  = cl_reg->cl_arbcnt;
                   1895:        arbsts  = cl_reg->cl_arbsts;
                   1896:
                   1897:        brbadru = cl_reg->cl_brbadru;
                   1898:        brbadrl = cl_reg->cl_brbadrl;
                   1899:        brbcnt  = cl_reg->cl_brbcnt;
                   1900:        brbsts  = cl_reg->cl_brbsts;
                   1901:
                   1902:        atbadru = cl_reg->cl_atbadru;
                   1903:        atbadrl = cl_reg->cl_atbadrl;
                   1904:        atbcnt  = cl_reg->cl_atbcnt;
                   1905:        atbsts  = cl_reg->cl_atbsts;
                   1906:
                   1907:        btbadru = cl_reg->cl_btbadru;
                   1908:        btbadrl = cl_reg->cl_btbadrl;
                   1909:        btbcnt  = cl_reg->cl_btbcnt;
                   1910:        btbsts  = cl_reg->cl_btbsts;
                   1911:
                   1912:        splx(s);
                   1913:
                   1914:        printf("{ port %x livr %x cmr %x\n",
                   1915:                  channel,livr,   cmr);
                   1916:        printf("cor1 %x cor2 %x cor3 %x cor4 %x cor5 %x cor6 %x cor7 %x\n",
                   1917:                cor1,   cor2,   cor3,   cor4,   cor5,   cor6,   cor7);
                   1918:        printf("schr1 %x schr2 %x schr3 %x schr4 %x\n",
                   1919:                schr1,   schr2,   schr3,   schr4);
                   1920:        printf("scrl %x scrh %x lnxt %x\n",
                   1921:                scrl,   scrh,   lnxt);
                   1922:        printf("rbpr %x rcor %x tbpr %x tcor %x\n",
                   1923:                rbpr,   rcor,   tbpr,   tcor);
                   1924:        printf("rpilr %x rir %x ier %x ccr %x\n",
                   1925:                rpilr,   rir,   ier,   ccr);
                   1926:        printf("tpr %x csr %x rts %x dtr %x\n",
                   1927:                tpr,   csr,   rts,   dtr);
                   1928:        printf("rtprl %x rtprh %x\n",
                   1929:                rtprl,   rtprh);
                   1930:        printf("rxcnt %lx txcnt %lx\n",
                   1931:                sc->sc_cl[channel].rxcnt, sc->sc_cl[channel].txcnt);
                   1932:        printf("dmabsts %x, tcbadru %x, tcbadrl %x, rcbadru %x, rcbadrl %x,\n",
                   1933:                dmabsts,    tcbadru,    tcbadrl,    rcbadru,    rcbadrl );
                   1934:        printf("parbadru %p, parbadrl %p, parbcnt %p, parbsts %p\n",
                   1935:                parbadru,    parbadrl,    parbcnt,    parbsts);
                   1936:        printf("arbadru %x, arbadrl %x, arbcnt %x, arbsts %x\n",
                   1937:                arbadru,    arbadrl,    arbcnt,    arbsts);
                   1938:        printf("brbadru %x, brbadrl %x, brbcnt %x, brbsts %x\n",
                   1939:                brbadru,    brbadrl,    brbcnt,    brbsts);
                   1940:        printf("atbadru %x, atbadrl %x, atbcnt %x, atbsts %x\n",
                   1941:                atbadru,    atbadrl,    atbcnt,    atbsts);
                   1942:        printf("btbadru %x, btbadrl %x, btbcnt %x, btbsts %x\n",
                   1943:                btbadru,    btbadrl,    btbcnt,    btbsts);
                   1944:        printf("}\n");
                   1945:        return;
                   1946: }
                   1947: #ifdef USE_BUFFER
                   1948: void
                   1949: cl_appendbuf(sc, channel, c)
                   1950:        struct clsoftc *sc;
                   1951:        u_char channel;
                   1952:        u_char c;
                   1953: {
                   1954:        /* int s; */
                   1955:        /* s = splcl(); */
                   1956:        if (1 + sc->sc_cl[channel].nchar >= CL_BUFSIZE ) {
                   1957:                cl_overflow (sc, channel, &sc->sc_fotime, "rbuf");
                   1958:                /* just toss the character */
                   1959:                return;
                   1960:        }
                   1961:        *(sc->sc_cl[channel].psupply++) = c;
                   1962:        if (&(sc->sc_cl[channel].buffer[CL_BUFSIZE])
                   1963:           == sc->sc_cl[channel].psupply) {
                   1964:                sc->sc_cl[channel].psupply = sc->sc_cl[channel].buffer;
                   1965:        }
                   1966:        sc->sc_cl[channel].nchar ++;
                   1967:        setsoftint(sc->ssir);
                   1968:        /* splx (s); */
                   1969:
                   1970: }
                   1971: void
                   1972: cl_appendbufn(sc, channel, buf, cnt)
                   1973:        struct clsoftc *sc;
                   1974:        u_char channel;
                   1975:        u_char *buf;
                   1976:        u_short cnt;
                   1977: {
                   1978:        /* int s; */
                   1979:        int i;
                   1980:        /* s = splcl(); */ /* should be called at splcl(). */
                   1981:        if (cnt + sc->sc_cl[channel].nchar >= CL_BUFSIZE ) {
                   1982:                cl_overflow (sc, channel, &sc->sc_fotime, "rbuf");
                   1983:                /* just toss the character(s)
                   1984:                 *  It could be argued that not all of the charactes
                   1985:                 *  should be tossed, just the ones that actually
                   1986:                 *  overflow the buffer. eh, O well.
                   1987:                 */
                   1988:                return;
                   1989:        }
                   1990:        for (i = 0; i < cnt; i++) {
                   1991:                *(sc->sc_cl[channel].psupply++) = buf[i];
                   1992:                if (&(sc->sc_cl[channel].buffer[CL_BUFSIZE]) == sc->sc_cl[channel].psupply)
                   1993:                {
                   1994:                        sc->sc_cl[channel].psupply = sc->sc_cl[channel].buffer;
                   1995:                }
                   1996:                sc->sc_cl[channel].nchar ++;
                   1997:        }
                   1998:        setsoftint(sc->ssir);
                   1999:        /* splx (s); */
                   2000: }
                   2001:
                   2002: void
                   2003: cl_softint(arg)
                   2004:        void *arg;
                   2005: {
                   2006:        struct clsoftc *sc = (struct clsoftc *)arg;
                   2007:        int i;
                   2008:        int s;
                   2009:        u_char c;
                   2010:        struct tty *tp;
                   2011:
                   2012:        for (i = 0 ; i < CLCD_PORTS_PER_CHIP; i ++) {
                   2013: /* printf("channel %x sc %x\n", i, sc); */
                   2014:                tp = sc->sc_cl[i].tty;
                   2015: /* printf("channel %x pconsum %x\n", i, sc->sc_cl[i].pconsum); */
                   2016:                while (sc->sc_cl[i].nchar > 0) {
                   2017:                        s = splcl();
                   2018:                        c = *(sc->sc_cl[i].pconsum++);
                   2019:                        if (&(sc->sc_cl[i].buffer[CL_BUFSIZE]) == sc->sc_cl[i].pconsum)
                   2020:                        {
                   2021:                                sc->sc_cl[i].pconsum = sc->sc_cl[i].buffer;
                   2022:                        }
                   2023:                        sc->sc_cl[i].nchar--;
                   2024:                        splx(s);
                   2025:                        (*linesw[tp->t_line].l_rint)(c,tp);
                   2026:                }
                   2027:        }
                   2028: }
                   2029: #endif

CVSweb