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

Annotation of sys/arch/mvme88k/dev/cl.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: cl.c,v 1.52 2006/05/08 14:36:10 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: #include <machine/psl.h>
        !            43:
        !            44: #include <dev/cons.h>
        !            45:
        !            46: #include <mvme88k/dev/clreg.h>
        !            47: #include <mvme88k/dev/pcctworeg.h>
        !            48: #include <mvme88k/dev/pcctwovar.h>
        !            49:
        !            50: #ifdef DDB
        !            51: #include <ddb/db_var.h>
        !            52: #endif
        !            53:
        !            54: #define splcl()        spltty()
        !            55:
        !            56: /* min timeout 0xa, what is a good value */
        !            57: #define CL_TIMEOUT     0x10
        !            58: #define CL_FIFO_MAX    0x10
        !            59: #define CL_FIFO_CNT    0xc
        !            60: #define        CL_RX_TIMEOUT   0x10
        !            61:
        !            62: #define CL_RXDMAINT    0x82
        !            63: #define CL_TXDMAINT    0x42
        !            64: #define CL_TXMASK      0x47
        !            65: #define CL_RXMASK      0x87
        !            66: #define CL_TXINTR      0x02
        !            67: #define CL_RXINTR      0x02
        !            68:
        !            69: struct cl_cons {
        !            70:        bus_space_tag_t         cl_iot;
        !            71:        bus_space_handle_t      cl_ioh;
        !            72:        volatile u_int8_t       *cl_rxiack;
        !            73:        u_int8_t                channel;
        !            74: } cl_cons;
        !            75:
        !            76: struct cl_info {
        !            77:        struct tty *tty;
        !            78:        u_char  cl_swflags;
        !            79:        u_char  cl_softchar;
        !            80:        u_char  cl_consio;
        !            81:        u_char  cl_speed;
        !            82:        u_char  cl_parstop;     /* parity, stop bits. */
        !            83:        u_char  cl_rxmode;
        !            84:        u_char  cl_txmode;
        !            85:        u_char  cl_clen;
        !            86:        u_char  cl_parity;
        !            87: #if 0
        !            88:        u_char  transmitting;
        !            89: #endif
        !            90:        u_long  txcnt;
        !            91:        u_long  rxcnt;
        !            92:
        !            93:        void *rx[2];
        !            94:        void *rxp[2];
        !            95:        void *tx[2];
        !            96:        void *txp[2];
        !            97: };
        !            98: #define CLCD_PORTS_PER_CHIP 4
        !            99: #define CL_BUFSIZE 256
        !           100:
        !           101: #ifndef DO_MALLOC
        !           102: /* four (4) buffers per port */
        !           103: char cl_dmabuf[CLCD_PORTS_PER_CHIP * CL_BUFSIZE * 4];
        !           104: char cl_dmabuf1[CLCD_PORTS_PER_CHIP * CL_BUFSIZE * 4];
        !           105: #endif
        !           106:
        !           107: struct clsoftc {
        !           108:        struct device           sc_dev;
        !           109:        bus_space_tag_t         sc_iot;
        !           110:        bus_space_handle_t      sc_ioh;
        !           111:        time_t                  sc_fotime;      /* time of last fifo overrun */
        !           112:        struct cl_info          sc_cl[CLCD_PORTS_PER_CHIP];
        !           113:        struct intrhand         sc_ih_e;
        !           114:        struct intrhand         sc_ih_m;
        !           115:        struct intrhand         sc_ih_t;
        !           116:        struct intrhand         sc_ih_r;
        !           117:        char                    sc_errintrname[16 + 4];
        !           118:        char                    sc_mxintrname[16 + 3];
        !           119:        char                    sc_rxintrname[16 + 3];
        !           120:        char                    sc_txintrname[16 + 3];
        !           121:        struct pcctwosoftc      *sc_pcctwo;
        !           122: };
        !           123:
        !           124: const struct {
        !           125:        u_int speed;
        !           126:        u_char divisor;
        !           127:        u_char clock;
        !           128:        u_char rx_timeout;
        !           129: } cl_clocks[] = {
        !           130:        { 64000, 0x26, 0, 0x01},
        !           131:        { 56000, 0x2c, 0, 0x01},
        !           132:        { 38400, 0x40, 0, 0x01},
        !           133:        { 19200, 0x81, 0, 0x02},
        !           134:        {  9600, 0x40, 1, 0x04},
        !           135:        {  7200, 0x56, 1, 0x04},
        !           136:        {  4800, 0x81, 1, 0x08},
        !           137:        {  3600, 0xad, 1, 0x08},
        !           138:        {  2400, 0x40, 2, 0x10},
        !           139:        {  1200, 0x81, 2, 0x20},
        !           140:        {   600, 0x40, 3, 0x40},
        !           141:        {   300, 0x81, 3, 0x80},
        !           142:        {   150, 0x40, 3, 0x80},
        !           143:        {   110, 0x58, 4, 0xff},
        !           144:        {    50, 0xC2, 4, 0xff},
        !           145:        {     0, 0x00, 0, 0},
        !           146: };
        !           147:
        !           148: #define        CL_SAFE_CLOCK   4       /* 9600 entry */
        !           149:
        !           150: /* prototypes */
        !           151: cons_decl(cl);
        !           152: int cl_instat(struct clsoftc *sc);
        !           153: u_int8_t cl_clkdiv(int speed);
        !           154: u_int8_t cl_clknum(int speed);
        !           155: u_int8_t cl_clkrxtimeout(int speed);
        !           156: void clstart(struct tty *tp);
        !           157: void cl_unblock(struct tty *tp);
        !           158: int clccparam(struct clsoftc *sc, struct termios *par, int channel);
        !           159:
        !           160: int clparam(struct tty *tp, struct termios *t);
        !           161: int cl_mintr(void *);
        !           162: int cl_txintr(void *);
        !           163: int cl_rxintr(void *);
        !           164: void cl_overflow(struct clsoftc *sc, int channel, long *ptime, char *msg);
        !           165: void cl_parity(struct clsoftc *sc, int channel);
        !           166: void cl_frame(struct clsoftc *sc, int channel);
        !           167: void cl_break( struct clsoftc *sc, int channel);
        !           168: int clmctl(dev_t dev, int bits, int how);
        !           169: #ifdef DEBUG
        !           170: void cl_dumpport(struct clsoftc *, int);
        !           171: #endif
        !           172:
        !           173: int    clprobe(struct device *parent, void *self, void *aux);
        !           174: void   clattach(struct device *parent, struct device *self, void *aux);
        !           175:
        !           176: void   cl_initchannel(struct clsoftc *sc, int channel);
        !           177: void   clputc(struct clsoftc *sc, int unit, u_char c);
        !           178:
        !           179: struct cfattach cl_ca = {
        !           180:        sizeof(struct clsoftc), clprobe, clattach
        !           181: };
        !           182:
        !           183: struct cfdriver cl_cd = {
        !           184:        NULL, "cl", DV_TTY
        !           185: };
        !           186:
        !           187: #if 0
        !           188: #define CLCDBUF 80
        !           189: void cloutput(struct tty *tp);
        !           190: #endif
        !           191:
        !           192: #define CL_UNIT(x) (minor(x) >> 2)
        !           193: #define CL_CHANNEL(x) (minor(x) & 3)
        !           194:
        !           195: struct tty *
        !           196: cltty(dev)
        !           197:        dev_t dev;
        !           198: {
        !           199:        int unit, channel;
        !           200:        struct clsoftc *sc;
        !           201:
        !           202:        unit = CL_UNIT(dev);
        !           203:        if (unit >= cl_cd.cd_ndevs ||
        !           204:            (sc = (struct clsoftc *)cl_cd.cd_devs[unit]) == NULL) {
        !           205:                return NULL;
        !           206:        }
        !           207:        channel = CL_CHANNEL(dev);
        !           208:        return sc->sc_cl[channel].tty;
        !           209: }
        !           210:
        !           211: int
        !           212: clprobe(parent, self, aux)
        !           213:        struct device *parent;
        !           214:        void *self;
        !           215:        void *aux;
        !           216: {
        !           217:        struct confargs *ca = aux;
        !           218:        bus_space_handle_t ioh;
        !           219:        int rc;
        !           220:
        !           221:        if (brdtyp == BRD_188)
        !           222:                return 0;
        !           223:
        !           224:        /*
        !           225:         * We do not accept empty locators here...
        !           226:         */
        !           227:        if (ca->ca_paddr == CD2400_BASE_ADDR ||
        !           228:            (ca->ca_paddr == CD2400_SECONDARY_ADDR && brdtyp == BRD_8120)) {
        !           229:                if (bus_space_map(ca->ca_iot, ca->ca_paddr, CD2400_SIZE,
        !           230:                    0, &ioh) != 0)
        !           231:                        return 0;
        !           232:                rc = badaddr((vaddr_t)bus_space_vaddr(ca->ca_iot, ioh), 1);
        !           233:                bus_space_unmap(ca->ca_iot, ioh, CD2400_SIZE);
        !           234:                return rc == 0;
        !           235:        }
        !           236:
        !           237:        return 0;
        !           238: }
        !           239:
        !           240: void
        !           241: clattach(parent, self, aux)
        !           242:        struct device *parent;
        !           243:        struct device *self;
        !           244:        void *aux;
        !           245: {
        !           246:        struct clsoftc *sc = (struct clsoftc *)self;
        !           247:        struct confargs *ca = aux;
        !           248:        bus_space_tag_t iot;
        !           249:        bus_space_handle_t ioh;
        !           250:        int i;
        !           251:
        !           252:        if (ca->ca_ipl < 0)
        !           253:                ca->ca_ipl = IPL_TTY;
        !           254:
        !           255:        iot = sc->sc_iot = ca->ca_iot;
        !           256:        if (bus_space_map(iot, ca->ca_paddr, CD2400_SIZE, 0, &ioh) != 0) {
        !           257:                printf(": can't map registers!\n");
        !           258:                return;
        !           259:        }
        !           260:        sc->sc_ioh = ioh;
        !           261:        sc->sc_pcctwo = (struct pcctwosoftc *)parent;
        !           262:
        !           263:        if (ca->ca_paddr == CD2400_BASE_ADDR) {
        !           264:                /*
        !           265:                 * Although we are still running using the BUG routines,
        !           266:                 * this device will be elected as the console after
        !           267:                 * autoconf. Mark it as such.
        !           268:                 */
        !           269:                sc->sc_cl[0].cl_consio = 1;
        !           270:                printf(": console");
        !           271:        } else {
        !           272:                /* reset chip only if we are not console device */
        !           273:                /* wait for GFRCR */
        !           274:        }
        !           275:        /* allow chip to settle before continuing */
        !           276:        delay(800);
        !           277:
        !           278:        /* set up global registers */
        !           279:        bus_space_write_1(iot, ioh, CL_TPR, CL_TIMEOUT);
        !           280:        bus_space_write_1(iot, ioh, CL_RPILR, 0x03);
        !           281:        bus_space_write_1(iot, ioh, CL_TPILR, 0x02);
        !           282:        bus_space_write_1(iot, ioh, CL_MPILR, 0x01);
        !           283:
        !           284: #ifdef DO_MALLOC
        !           285:        sc->sc_cl[0].rx[0] = (void *)(dvma_malloc(16 * CL_BUFSIZE));
        !           286: #else
        !           287:        /* XXX */
        !           288:        if ((vaddr_t)ca->ca_paddr == CD2400_BASE_ADDR)
        !           289:                sc->sc_cl[0].rx[0] = (void *)(&cl_dmabuf);
        !           290:        else
        !           291:                sc->sc_cl[0].rx[0] = (void *)(&cl_dmabuf1);
        !           292: #endif
        !           293:        sc->sc_cl[0].rx[1] = (void *)(((int)sc->sc_cl[0].rx[0]) + CL_BUFSIZE);
        !           294:        sc->sc_cl[1].rx[0] = (void *)(((int)sc->sc_cl[0].rx[1]) + CL_BUFSIZE);
        !           295:        sc->sc_cl[1].rx[1] = (void *)(((int)sc->sc_cl[1].rx[0]) + CL_BUFSIZE);
        !           296:
        !           297:        sc->sc_cl[2].rx[0] = (void *)(((int)sc->sc_cl[1].rx[1]) + CL_BUFSIZE);
        !           298:        sc->sc_cl[2].rx[1] = (void *)(((int)sc->sc_cl[2].rx[0]) + CL_BUFSIZE);
        !           299:        sc->sc_cl[3].rx[0] = (void *)(((int)sc->sc_cl[2].rx[1]) + CL_BUFSIZE);
        !           300:        sc->sc_cl[3].rx[1] = (void *)(((int)sc->sc_cl[3].rx[0]) + CL_BUFSIZE);
        !           301:
        !           302:        sc->sc_cl[0].tx[0] = (void *)(((int)sc->sc_cl[3].rx[1]) + CL_BUFSIZE);
        !           303:        sc->sc_cl[0].tx[1] = (void *)(((int)sc->sc_cl[0].tx[0]) + CL_BUFSIZE);
        !           304:        sc->sc_cl[1].tx[0] = (void *)(((int)sc->sc_cl[0].tx[1]) + CL_BUFSIZE);
        !           305:        sc->sc_cl[1].tx[1] = (void *)(((int)sc->sc_cl[1].tx[0]) + CL_BUFSIZE);
        !           306:
        !           307:        sc->sc_cl[2].tx[0] = (void *)(((int)sc->sc_cl[1].tx[1]) + CL_BUFSIZE);
        !           308:        sc->sc_cl[2].tx[1] = (void *)(((int)sc->sc_cl[2].tx[0]) + CL_BUFSIZE);
        !           309:        sc->sc_cl[3].tx[0] = (void *)(((int)sc->sc_cl[2].tx[1]) + CL_BUFSIZE);
        !           310:        sc->sc_cl[3].tx[1] = (void *)(((int)sc->sc_cl[3].tx[0]) + CL_BUFSIZE);
        !           311:        for (i = 0; i < CLCD_PORTS_PER_CHIP; i++) {
        !           312: #if 0
        !           313:                int j;
        !           314:
        !           315:                for (j = 0; j < 2 ; j++) {
        !           316:                        sc->sc_cl[i].rxp[j] = (void *)kvtop(sc->sc_cl[i].rx[j]);
        !           317:                        printf("cl[%d].rxbuf[%d] %x p %x\n",
        !           318:                            i, j, sc->sc_cl[i].rx[j], sc->sc_cl[i].rxp[j]);
        !           319:                        sc->sc_cl[i].txp[j] = (void *)kvtop(sc->sc_cl[i].tx[j]);
        !           320:                        printf("cl[%d].txbuf[%d] %x p %x\n",
        !           321:                            i, j, sc->sc_cl[i].tx[j], sc->sc_cl[i].txp[j]);
        !           322:                }
        !           323: #endif
        !           324: #if 0
        !           325:                sc->sc_cl[i].cl_rxmode =
        !           326:                        !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x01));
        !           327:                sc->sc_cl[i].cl_txmode =
        !           328:                        !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x02));
        !           329:                sc->sc_cl[i].cl_softchar =
        !           330:                        !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x04));
        !           331: #endif
        !           332:                cl_initchannel(sc, i);
        !           333:        }
        !           334:
        !           335:        /* clear errors */
        !           336:        bus_space_write_1(sc->sc_pcctwo->sc_iot, sc->sc_pcctwo->sc_ioh,
        !           337:            PCCTWO_SCCERR, 0x01);
        !           338:
        !           339:        /* enable interrupts */
        !           340:        sc->sc_ih_e.ih_fn = cl_rxintr;
        !           341:        sc->sc_ih_e.ih_arg = sc;
        !           342:        sc->sc_ih_e.ih_wantframe = 0;
        !           343:        sc->sc_ih_e.ih_ipl = ca->ca_ipl;
        !           344:
        !           345:        sc->sc_ih_m.ih_fn = cl_mintr;
        !           346:        sc->sc_ih_m.ih_arg = sc;
        !           347:        sc->sc_ih_m.ih_wantframe = 0;
        !           348:        sc->sc_ih_m.ih_ipl = ca->ca_ipl;
        !           349:
        !           350:        sc->sc_ih_t.ih_fn = cl_txintr;
        !           351:        sc->sc_ih_t.ih_arg = sc;
        !           352:        sc->sc_ih_t.ih_wantframe = 0;
        !           353:        sc->sc_ih_t.ih_ipl = ca->ca_ipl;
        !           354:
        !           355:        sc->sc_ih_r.ih_fn = cl_rxintr;
        !           356:        sc->sc_ih_r.ih_arg = sc;
        !           357:        sc->sc_ih_r.ih_wantframe = 0;
        !           358:        sc->sc_ih_r.ih_ipl = ca->ca_ipl;
        !           359:
        !           360:        snprintf(sc->sc_errintrname, sizeof sc->sc_errintrname,
        !           361:            "%s_err", self->dv_xname);
        !           362:        snprintf(sc->sc_mxintrname, sizeof sc->sc_mxintrname,
        !           363:            "%s_mx", self->dv_xname);
        !           364:        snprintf(sc->sc_rxintrname, sizeof sc->sc_rxintrname,
        !           365:            "%s_rx", self->dv_xname);
        !           366:        snprintf(sc->sc_txintrname, sizeof sc->sc_txintrname,
        !           367:            "%s_tx", self->dv_xname);
        !           368:
        !           369:        pcctwointr_establish(PCC2V_SCC_RXE, &sc->sc_ih_e, sc->sc_errintrname);
        !           370:        pcctwointr_establish(PCC2V_SCC_M, &sc->sc_ih_m, sc->sc_mxintrname);
        !           371:        pcctwointr_establish(PCC2V_SCC_TX, &sc->sc_ih_t, sc->sc_txintrname);
        !           372:        pcctwointr_establish(PCC2V_SCC_RX, &sc->sc_ih_r, sc->sc_rxintrname);
        !           373:
        !           374:        bus_space_write_1(sc->sc_pcctwo->sc_iot, sc->sc_pcctwo->sc_ioh,
        !           375:            PCCTWO_SCCICR, PCC2_IRQ_IEN | (ca->ca_ipl & PCC2_IRQ_IPL));
        !           376:        bus_space_write_1(sc->sc_pcctwo->sc_iot, sc->sc_pcctwo->sc_ioh,
        !           377:            PCCTWO_SCCTX, PCC2_IRQ_IEN | (ca->ca_ipl & PCC2_IRQ_IPL));
        !           378:        bus_space_write_1(sc->sc_pcctwo->sc_iot, sc->sc_pcctwo->sc_ioh,
        !           379:            PCCTWO_SCCRX, PCC2_IRQ_IEN | (ca->ca_ipl & PCC2_IRQ_IPL));
        !           380:
        !           381:        printf("\n");
        !           382: }
        !           383:
        !           384: void
        !           385: cl_initchannel(sc, channel)
        !           386:        struct clsoftc *sc;
        !           387:        int channel;
        !           388: {
        !           389:        int s;
        !           390:        bus_space_tag_t iot;
        !           391:        bus_space_handle_t ioh;
        !           392:
        !           393:        iot = sc->sc_iot;
        !           394:        ioh = sc->sc_ioh;
        !           395:
        !           396:        /* set up option registers */
        !           397:        sc->sc_cl[channel].tty = NULL;
        !           398:        s = splhigh();
        !           399:
        !           400:        bus_space_write_1(iot, ioh, CL_CAR, channel);
        !           401:        bus_space_write_1(iot, ioh, CL_LIVR, PCC2_VECT + PCC2V_SCC_RXE);
        !           402:        bus_space_write_1(iot, ioh, CL_IER, 0);
        !           403:
        !           404:        if (sc->sc_cl[channel].cl_consio == 0) {
        !           405:                bus_space_write_1(iot, ioh, CL_CMR, 0x02);
        !           406:                bus_space_write_1(iot, ioh, CL_COR1, 0x17);
        !           407:                bus_space_write_1(iot, ioh, CL_COR2, 0x00);
        !           408:                bus_space_write_1(iot, ioh, CL_COR3, 0x02);
        !           409:                bus_space_write_1(iot, ioh, CL_COR4, 0xec);
        !           410:                bus_space_write_1(iot, ioh, CL_COR5, 0xec);
        !           411:                bus_space_write_1(iot, ioh, CL_COR6, 0x00);
        !           412:                bus_space_write_1(iot, ioh, CL_COR7, 0x00);
        !           413:                bus_space_write_1(iot, ioh, CL_SCHR1, 0x00);
        !           414:                bus_space_write_1(iot, ioh, CL_SCHR2, 0x00);
        !           415:                bus_space_write_1(iot, ioh, CL_SCHR3, 0x00);
        !           416:                bus_space_write_1(iot, ioh, CL_SCHR4, 0x00);
        !           417:                bus_space_write_1(iot, ioh, CL_SCRL, 0x00);
        !           418:                bus_space_write_1(iot, ioh, CL_SCRH, 0x00);
        !           419:                bus_space_write_1(iot, ioh, CL_LNXT, 0x00);
        !           420:                bus_space_write_1(iot, ioh, CL_RBPR, 0x40);     /* 9600 */
        !           421:                bus_space_write_1(iot, ioh, CL_RCOR, 0x01);
        !           422:                bus_space_write_1(iot, ioh, CL_TBPR, 0x40);     /* 9600 */
        !           423:                bus_space_write_1(iot, ioh, CL_TCOR, 0x01 << 5);
        !           424:                /* console port should be 0x88 already */
        !           425:                bus_space_write_1(iot, ioh, CL_MSVR_RTS, 0x00);
        !           426:                bus_space_write_1(iot, ioh, CL_MSVR_DTR, 0x00);
        !           427:                bus_space_write_1(iot, ioh, CL_RTPRL, CL_RX_TIMEOUT);
        !           428:                bus_space_write_1(iot, ioh, CL_RTPRH, 0x00);
        !           429:        }
        !           430:        bus_space_write_1(iot, ioh, CL_CCR, 0x20);
        !           431:        while (bus_space_read_1(iot, ioh, CL_CCR) != 0)
        !           432:                ;
        !           433:
        !           434:        splx(s);
        !           435: }
        !           436:
        !           437:
        !           438: int cldefaultrate = TTYDEF_SPEED;
        !           439:
        !           440: int
        !           441: clmctl(dev, bits, how)
        !           442:        dev_t dev;
        !           443:        int bits;
        !           444:        int how;
        !           445: {
        !           446:        struct clsoftc *sc;
        !           447:        bus_space_tag_t iot;
        !           448:        bus_space_handle_t ioh;
        !           449:        int s;
        !           450:
        !           451:        /* should only be called with valid device */
        !           452:        sc = (struct clsoftc *)cl_cd.cd_devs[CL_UNIT(dev)];
        !           453:        iot = sc->sc_iot;
        !           454:        ioh = sc->sc_ioh;
        !           455:
        !           456:        /* settings are currently ignored */
        !           457:        s = splcl();
        !           458:        switch (how) {
        !           459:        case DMSET:
        !           460:                if (bits & TIOCM_RTS)
        !           461:                        bus_space_write_1(iot, ioh, CL_MSVR_RTS, 0x01);
        !           462:                else
        !           463:                        bus_space_write_1(iot, ioh, CL_MSVR_RTS, 0x00);
        !           464:                if (bits & TIOCM_DTR)
        !           465:                        bus_space_write_1(iot, ioh, CL_MSVR_DTR, 0x02);
        !           466:                else
        !           467:                        bus_space_write_1(iot, ioh, CL_MSVR_DTR, 0x00);
        !           468:                break;
        !           469:
        !           470:        case DMBIC:
        !           471:                if (bits & TIOCM_RTS)
        !           472:                        bus_space_write_1(iot, ioh, CL_MSVR_RTS, 0x00);
        !           473:                if (bits & TIOCM_DTR)
        !           474:                        bus_space_write_1(iot, ioh, CL_MSVR_DTR, 0x00);
        !           475:                break;
        !           476:
        !           477:        case DMBIS:
        !           478:                if (bits & TIOCM_RTS)
        !           479:                        bus_space_write_1(iot, ioh, CL_MSVR_RTS, 0x01);
        !           480:                if (bits & TIOCM_DTR)
        !           481:                        bus_space_write_1(iot, ioh, CL_MSVR_DTR, 0x02);
        !           482:                break;
        !           483:
        !           484:        case DMGET:
        !           485:                bits = 0;
        !           486:
        !           487:                {
        !           488:                        u_int8_t msvr;
        !           489:
        !           490:                        msvr = bus_space_read_1(iot, ioh, CL_MSVR_RTS);
        !           491:                        if (msvr & 0x80)
        !           492:                                bits |= TIOCM_DSR;
        !           493:                        if (msvr & 0x40)
        !           494:                                bits |= TIOCM_CD;
        !           495:                        if (msvr & 0x20)
        !           496:                                bits |= TIOCM_CTS;
        !           497:                        if (msvr & 0x10)
        !           498:                                bits |= TIOCM_DTR;
        !           499:                        if (msvr & 0x02)
        !           500:                                bits |= TIOCM_DTR;
        !           501:                        if (msvr & 0x01)
        !           502:                                bits |= TIOCM_RTS;
        !           503:                }
        !           504:                break;
        !           505:        }
        !           506:        splx(s);
        !           507: #if 0
        !           508:        bits = 0;
        !           509:        /* proper defaults? */
        !           510:        bits |= TIOCM_DTR;
        !           511:        bits |= TIOCM_RTS;
        !           512:        bits |= TIOCM_CTS;
        !           513:        bits |= TIOCM_CD;
        !           514:        /*      bits |= TIOCM_RI; */
        !           515:        bits |= TIOCM_DSR;
        !           516: #endif
        !           517:
        !           518:        return bits;
        !           519: }
        !           520:
        !           521: int
        !           522: clopen(dev, flag, mode, p)
        !           523:        dev_t dev;
        !           524:        int flag;
        !           525:        int mode;
        !           526:        struct proc *p;
        !           527: {
        !           528:        int s, unit, channel;
        !           529:        struct cl_info *cl;
        !           530:        struct clsoftc *sc;
        !           531:        struct tty *tp;
        !           532:
        !           533:        unit = CL_UNIT(dev);
        !           534:        if (unit >= cl_cd.cd_ndevs ||
        !           535:            (sc = (struct clsoftc *)cl_cd.cd_devs[unit]) == NULL) {
        !           536:                return ENODEV;
        !           537:        }
        !           538:
        !           539:        channel = CL_CHANNEL(dev);
        !           540:        cl = &sc->sc_cl[channel];
        !           541:
        !           542:        s = splcl();
        !           543:        if (cl->tty) {
        !           544:                tp = cl->tty;
        !           545:        } else {
        !           546:                tp = cl->tty = ttymalloc();
        !           547:        }
        !           548:        tp->t_oproc = clstart;
        !           549:        tp->t_param = clparam;
        !           550:        tp->t_dev = dev;
        !           551:
        !           552:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           553:                tp->t_state |= TS_WOPEN;
        !           554:                ttychars(tp);
        !           555:                if (tp->t_ispeed == 0) {
        !           556:                        /*
        !           557:                         * only when cleared do we reset to defaults.
        !           558:                         */
        !           559:                        tp->t_iflag = TTYDEF_IFLAG;
        !           560:                        tp->t_oflag = TTYDEF_OFLAG;
        !           561:                        tp->t_lflag = TTYDEF_LFLAG;
        !           562:                        tp->t_ispeed = tp->t_ospeed = cldefaultrate;
        !           563:
        !           564:                        if (sc->sc_cl[channel].cl_consio != 0) {
        !           565:                                /* console is 8N1 */
        !           566:                                tp->t_cflag = (CREAD | CS8 | HUPCL);
        !           567:                        } else {
        !           568:                                tp->t_cflag = TTYDEF_CFLAG;
        !           569:                        }
        !           570:                }
        !           571:                /*
        !           572:                 * do these all the time
        !           573:                 */
        !           574:                if (cl->cl_swflags & TIOCFLAG_CLOCAL)
        !           575:                        tp->t_cflag |= CLOCAL;
        !           576:                if (cl->cl_swflags & TIOCFLAG_CRTSCTS)
        !           577:                        tp->t_cflag |= CRTSCTS;
        !           578:                if (cl->cl_swflags & TIOCFLAG_MDMBUF)
        !           579:                        tp->t_cflag |= MDMBUF;
        !           580:                clparam(tp, &tp->t_termios);
        !           581:                ttsetwater(tp);
        !           582:
        !           583:                (void)clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
        !           584: #ifdef XXX
        !           585:                if ((cl->cl_swflags & TIOCFLAG_SOFTCAR) ||
        !           586:                        (clmctl(dev, 0, DMGET) & TIOCM_CD)) {
        !           587:                        tp->t_state |= TS_CARR_ON;
        !           588:                } else {
        !           589:                        tp->t_state &= ~TS_CARR_ON;
        !           590:                }
        !           591: #endif
        !           592:                tp->t_state |= TS_CARR_ON;
        !           593:                {
        !           594:                        u_int8_t save;
        !           595:
        !           596:                        save = bus_space_read_1(sc->sc_iot, sc->sc_ioh, CL_CAR);
        !           597:                        bus_space_write_1(sc->sc_iot, sc->sc_ioh, CL_CAR,
        !           598:                            channel);
        !           599:                        bus_space_write_1(sc->sc_iot, sc->sc_ioh, CL_IER, 0x88);
        !           600:                        bus_space_write_1(sc->sc_iot, sc->sc_ioh, CL_CAR,
        !           601:                            save);
        !           602:                }
        !           603:        } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
        !           604:                splx(s);
        !           605:                return EBUSY;
        !           606:        }
        !           607:        splx(s);
        !           608:
        !           609:        /*
        !           610:         * Reset the tty pointer, as there could have been a dialout
        !           611:         * use of the tty with a dialin open waiting.
        !           612:         */
        !           613:        tp->t_dev = dev;
        !           614: #ifdef DEBUG
        !           615:        cl_dumpport(sc, channel);
        !           616: #endif
        !           617:        return (*linesw[tp->t_line].l_open)(dev, tp);
        !           618: }
        !           619:
        !           620: int
        !           621: clparam(tp, t)
        !           622:        struct tty *tp;
        !           623:        struct termios *t;
        !           624: {
        !           625:        int unit, channel;
        !           626:        struct clsoftc *sc;
        !           627:        int s;
        !           628:        dev_t dev;
        !           629:
        !           630:        dev = tp->t_dev;
        !           631:        unit = CL_UNIT(dev);
        !           632:        if (unit >= cl_cd.cd_ndevs ||
        !           633:            (sc = (struct clsoftc *)cl_cd.cd_devs[unit]) == NULL) {
        !           634:                return ENODEV;
        !           635:        }
        !           636:        channel = CL_CHANNEL(dev);
        !           637:        tp->t_ispeed = t->c_ispeed;
        !           638:        tp->t_ospeed = t->c_ospeed;
        !           639:        tp->t_cflag = t->c_cflag;
        !           640:        clccparam(sc, t, channel);
        !           641:        s = splcl();
        !           642:        cl_unblock(tp);
        !           643:        splx(s);
        !           644:        return 0;
        !           645: }
        !           646:
        !           647: #if 0
        !           648: void
        !           649: cloutput(tp)
        !           650:        struct tty *tp;
        !           651: {
        !           652:        int cc, s, unit, cnt;
        !           653:        u_char *tptr;
        !           654:        int channel;
        !           655:        struct clsoftc *sc;
        !           656:        dev_t dev;
        !           657:        u_char cl_obuffer[CLCDBUF+1];
        !           658:
        !           659:        dev = tp->t_dev;
        !           660:        unit = CL_UNIT(dev);
        !           661:        if (unit >= cl_cd.cd_ndevs ||
        !           662:            (sc = (struct clsoftc *)cl_cd.cd_devs[unit]) == NULL) {
        !           663:                return;
        !           664:        }
        !           665:        channel = CL_CHANNEL(dev);
        !           666:
        !           667:        if ((tp->t_state & TS_ISOPEN) == 0)
        !           668:                return;
        !           669:
        !           670:        s = splcl();
        !           671:        cc = tp->t_outq.c_cc;
        !           672:        while (cc > 0) {
        !           673: /*XXX*/
        !           674:                cnt = min (CLCDBUF,cc);
        !           675:                cnt = q_to_b(&tp->t_outq, cl_obuffer, cnt);
        !           676:                if (cnt == 0) {
        !           677:                        break;
        !           678:                }
        !           679:                for (tptr = cl_obuffer; tptr < &cl_obuffer[cnt]; tptr++) {
        !           680:                        clputc(sc, channel, *tptr);
        !           681:                }
        !           682:                cc -= cnt;
        !           683:        }
        !           684:        splx(s);
        !           685: }
        !           686: #endif
        !           687:
        !           688: int
        !           689: clclose(dev, flag, mode, p)
        !           690:        dev_t dev;
        !           691:        int flag;
        !           692:        int mode;
        !           693:        struct proc *p;
        !           694: {
        !           695:        int unit, channel;
        !           696:        struct tty *tp;
        !           697:        struct cl_info *cl;
        !           698:        struct clsoftc *sc;
        !           699:        bus_space_tag_t iot;
        !           700:        bus_space_handle_t ioh;
        !           701:        int s;
        !           702:
        !           703:        unit = CL_UNIT(dev);
        !           704:        if (unit >= cl_cd.cd_ndevs ||
        !           705:            (sc = (struct clsoftc *)cl_cd.cd_devs[unit]) == NULL) {
        !           706:                return ENODEV;
        !           707:        }
        !           708:        channel = CL_CHANNEL(dev);
        !           709:        cl = &sc->sc_cl[channel];
        !           710:        iot = sc->sc_iot;
        !           711:        ioh = sc->sc_ioh;
        !           712:        tp = cl->tty;
        !           713:        (*linesw[tp->t_line].l_close)(tp, flag);
        !           714:
        !           715:        s = splcl();
        !           716:        bus_space_write_1(iot, ioh, CL_CAR, channel);
        !           717:        if (cl->cl_consio == 0 && (tp->t_cflag & HUPCL) != 0) {
        !           718:                bus_space_write_1(iot, ioh, CL_MSVR_RTS, 0x00);
        !           719:                bus_space_write_1(iot, ioh, CL_MSVR_DTR, 0x00);
        !           720:                bus_space_write_1(iot, ioh, CL_CCR, 0x05);
        !           721:        }
        !           722:
        !           723:
        !           724:        splx(s);
        !           725:        ttyclose(tp);
        !           726:
        !           727: #if 0
        !           728:        cl->tty = NULL;
        !           729: #endif
        !           730: #ifdef DEBUG
        !           731:        cl_dumpport(sc, channel);
        !           732: #endif
        !           733:
        !           734:        return 0;
        !           735: }
        !           736:
        !           737: int
        !           738: clread(dev, uio, flag)
        !           739:        dev_t dev;
        !           740:        struct uio *uio;
        !           741:        int flag;
        !           742: {
        !           743:        int unit, channel;
        !           744:        struct tty *tp;
        !           745:        struct cl_info *cl;
        !           746:        struct clsoftc *sc;
        !           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:        if (tp == NULL)
        !           756:                return ENXIO;
        !           757:        return (*linesw[tp->t_line].l_read)(tp, uio, flag);
        !           758: }
        !           759:
        !           760: int
        !           761: clwrite(dev, uio, flag)
        !           762:        dev_t dev;
        !           763:        struct uio *uio;
        !           764:        int flag;
        !           765: {
        !           766:        int unit, channel;
        !           767:        struct tty *tp;
        !           768:        struct cl_info *cl;
        !           769:        struct clsoftc *sc;
        !           770:        unit = CL_UNIT(dev);
        !           771:        if (unit >= cl_cd.cd_ndevs ||
        !           772:            (sc = (struct clsoftc *)cl_cd.cd_devs[unit]) == NULL) {
        !           773:                return ENODEV;
        !           774:        }
        !           775:        channel = CL_CHANNEL(dev);
        !           776:        cl = &sc->sc_cl[channel];
        !           777:        tp = cl->tty;
        !           778:        if (tp == NULL)
        !           779:                return ENXIO;
        !           780:        return (*linesw[tp->t_line].l_write)(tp, uio, flag);
        !           781: }
        !           782:
        !           783: int
        !           784: clioctl(dev, cmd, data, flag, p)
        !           785:        dev_t dev;
        !           786:        u_long cmd;
        !           787:        caddr_t data;
        !           788:        int flag;
        !           789:        struct proc *p;
        !           790: {
        !           791:        int error;
        !           792:        int unit, channel;
        !           793:        struct tty *tp;
        !           794:        struct cl_info *cl;
        !           795:        struct clsoftc *sc;
        !           796:        unit = CL_UNIT(dev);
        !           797:        if (unit >= cl_cd.cd_ndevs ||
        !           798:            (sc = (struct clsoftc *)cl_cd.cd_devs[unit]) == NULL) {
        !           799:                return ENODEV;
        !           800:        }
        !           801:        channel = CL_CHANNEL(dev);
        !           802:        cl = &sc->sc_cl[channel];
        !           803:        tp = cl->tty;
        !           804:        if (tp == NULL)
        !           805:                return ENXIO;
        !           806:
        !           807:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
        !           808:        if (error >= 0)
        !           809:                return error;
        !           810:
        !           811:        error = ttioctl(tp, cmd, data, flag, p);
        !           812:        if (error >= 0)
        !           813:                return error;
        !           814:
        !           815:        switch (cmd) {
        !           816:        case TIOCSBRK:
        !           817:                /* */
        !           818:                break;
        !           819:
        !           820:        case TIOCCBRK:
        !           821:                /* */
        !           822:                break;
        !           823:
        !           824:        case TIOCSDTR:
        !           825:                (void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
        !           826:                break;
        !           827:
        !           828:        case TIOCCDTR:
        !           829:                (void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
        !           830:                break;
        !           831:
        !           832:        case TIOCMSET:
        !           833:                (void) clmctl(dev, *(int *) data, DMSET);
        !           834:                break;
        !           835:
        !           836:        case TIOCMBIS:
        !           837:                (void) clmctl(dev, *(int *) data, DMBIS);
        !           838:                break;
        !           839:
        !           840:        case TIOCMBIC:
        !           841:                (void) clmctl(dev, *(int *) data, DMBIC);
        !           842:                break;
        !           843:
        !           844:        case TIOCMGET:
        !           845:                *(int *)data = clmctl(dev, 0, DMGET);
        !           846:                break;
        !           847:        case TIOCGFLAGS:
        !           848:                *(int *)data = cl->cl_swflags;
        !           849:                break;
        !           850:        case TIOCSFLAGS:
        !           851:                error = suser(p, 0);
        !           852:                if (error != 0)
        !           853:                        return EPERM;
        !           854:
        !           855:                cl->cl_swflags = *(int *)data;
        !           856:                cl->cl_swflags &= /* only allow valid flags */
        !           857:                        (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
        !           858:                break;
        !           859:        default:
        !           860:                return ENOTTY;
        !           861:        }
        !           862:
        !           863:        return 0;
        !           864: }
        !           865:
        !           866: int
        !           867: clstop(tp, flag)
        !           868:        struct tty *tp;
        !           869:        int flag;
        !           870: {
        !           871:        int s;
        !           872:
        !           873:        s = splcl();
        !           874:        if (tp->t_state & TS_BUSY) {
        !           875:                if ((tp->t_state & TS_TTSTOP) == 0)
        !           876:                        tp->t_state |= TS_FLUSH;
        !           877:        }
        !           878:        splx(s);
        !           879:        return 0;
        !           880: }
        !           881:
        !           882: void
        !           883: clcnprobe(cp)
        !           884:        struct consdev *cp;
        !           885: {
        !           886:        int maj;
        !           887:
        !           888:        /* bomb if it'a a MVME188 */
        !           889:        if (brdtyp == BRD_188 || badaddr(CD2400_BASE_ADDR, 1) != 0)
        !           890:                return;
        !           891:
        !           892:        /* do not attach as console if cl has been disabled */
        !           893:        if (cl_cd.cd_ndevs == 0 || cl_cd.cd_devs[0] == NULL)
        !           894:                return;
        !           895:
        !           896:        /* locate the major number */
        !           897:        for (maj = 0; maj < nchrdev; maj++)
        !           898:                if (cdevsw[maj].d_open == clopen)
        !           899:                        break;
        !           900:        if (maj == nchrdev)
        !           901:                return;
        !           902:
        !           903:        cp->cn_dev = makedev(maj, 0);
        !           904:        cp->cn_pri = CN_NORMAL;
        !           905: }
        !           906:
        !           907: void
        !           908: clcninit(cp)
        !           909:        struct consdev *cp;
        !           910: {
        !           911:        struct clsoftc *sc;
        !           912:
        !           913:        sc = (struct clsoftc *)cl_cd.cd_devs[0];
        !           914:        cl_cons.cl_iot = sc->sc_iot;
        !           915:        cl_cons.cl_ioh = sc->sc_ioh;
        !           916:        cl_cons.cl_rxiack = (void *)(sc->sc_pcctwo->sc_base + PCCTWO_SCCRXIACK);
        !           917: }
        !           918:
        !           919: int
        !           920: cl_instat(sc)
        !           921:        struct clsoftc *sc;
        !           922: {
        !           923:        u_int8_t rir;
        !           924:
        !           925:        if (sc == NULL)
        !           926:                rir = bus_space_read_1(cl_cons.cl_iot, cl_cons.cl_ioh, CL_RIR);
        !           927:        else
        !           928:                rir = bus_space_read_1(sc->sc_iot, sc->sc_ioh, CL_RIR);
        !           929:
        !           930:        return (rir & 0x40);
        !           931: }
        !           932:
        !           933: int
        !           934: clcngetc(dev)
        !           935:        dev_t dev;
        !           936: {
        !           937:        u_int8_t val, reoir, licr, data;
        !           938:        int got_char = 0;
        !           939:        u_int8_t ier_old;
        !           940:        bus_space_tag_t iot;
        !           941:        bus_space_handle_t ioh;
        !           942:
        !           943:        iot = cl_cons.cl_iot;
        !           944:        ioh = cl_cons.cl_ioh;
        !           945:
        !           946:        bus_space_write_1(iot, ioh, CL_CAR, 0);
        !           947:        ier_old = bus_space_read_1(iot, ioh, CL_IER);
        !           948:        if ((ier_old & 0x08) == 0) {
        !           949:                bus_space_write_1(iot, ioh, CL_IER, 0x08);
        !           950:        } else
        !           951:                ier_old = 0xff;
        !           952:
        !           953:        while (got_char == 0) {
        !           954:                val = bus_space_read_1(iot, ioh, CL_RIR);
        !           955:                /* if no receive interrupt pending wait */
        !           956:                if ((val & 0x80) == 0)
        !           957:                        continue;
        !           958:
        !           959:                /* XXX do we need to suck the entire FIFO contents? */
        !           960:                reoir = *cl_cons.cl_rxiack; /* receive PIACK */
        !           961:                licr = bus_space_read_1(iot, ioh, CL_LICR);
        !           962:                /* is the interrupt for us? (port 0) */
        !           963:                if (((licr >> 2) & 0x3) == 0) {
        !           964:                        (void)bus_space_read_1(iot, ioh, CL_RISRL);
        !           965:                        (void)bus_space_read_1(iot, ioh, CL_RFOC);
        !           966:                        data = bus_space_read_1(iot, ioh, CL_RDR);
        !           967:                        if (ier_old != 0xff)
        !           968:                                bus_space_write_1(iot, ioh, CL_IER, ier_old);
        !           969:                        got_char = 1;
        !           970:                } else {
        !           971:                        /* read and discard the character */
        !           972:                        data = bus_space_read_1(iot, ioh, CL_RDR);
        !           973:                }
        !           974:                bus_space_write_1(iot, ioh, CL_TEOIR, 0x00);
        !           975:        }
        !           976:
        !           977:        return data;
        !           978: }
        !           979:
        !           980: void
        !           981: clcnputc(dev, c)
        !           982:        dev_t dev;
        !           983:        u_char c;
        !           984: {
        !           985:        clputc(0, 0, c);
        !           986: }
        !           987:
        !           988: void
        !           989: clcnpollc(dev, on)
        !           990:        dev_t dev;
        !           991:        int on;
        !           992: {
        !           993:        if (on != 0) {
        !           994:                /* enable polling */
        !           995:        } else {
        !           996:                /* disable polling */
        !           997:        }
        !           998: }
        !           999:
        !          1000: void
        !          1001: clputc(sc, unit, c)
        !          1002:        struct clsoftc *sc;
        !          1003:        int unit;
        !          1004:        u_char c;
        !          1005: {
        !          1006:        u_int8_t schar;
        !          1007:        u_int8_t oldchannel;
        !          1008:        bus_space_tag_t iot;
        !          1009:        bus_space_handle_t ioh;
        !          1010:        int s;
        !          1011:
        !          1012:        if (sc == NULL) {
        !          1013:                /* output on console */
        !          1014:                iot = cl_cons.cl_iot;
        !          1015:                ioh = cl_cons.cl_ioh;
        !          1016:        } else {
        !          1017:                iot = sc->sc_iot;
        !          1018:                ioh = sc->sc_ioh;
        !          1019:        }
        !          1020:
        !          1021:        s = splhigh();
        !          1022:        oldchannel = bus_space_read_1(iot, ioh, CL_CAR);
        !          1023:        bus_space_write_1(iot, ioh, CL_CAR, unit);
        !          1024:        if (unit == 0) {
        !          1025:                schar = bus_space_read_1(iot, ioh, CL_SCHR3);
        !          1026:                /* send special char, number 3 */
        !          1027:                bus_space_write_1(iot, ioh, CL_SCHR3, c);
        !          1028:                bus_space_write_1(iot, ioh, CL_STCR, 0x08 | 3);
        !          1029:                while (bus_space_read_1(iot, ioh, CL_STCR) != 0) {
        !          1030:                        /* wait until cl notices the command
        !          1031:                         * otherwise it may not notice the character
        !          1032:                         * if we send characters too fast.
        !          1033:                         */
        !          1034:                }
        !          1035:                DELAY(5);
        !          1036:                bus_space_write_1(iot, ioh, CL_SCHR3, schar);
        !          1037:        } else {
        !          1038:                if (bus_space_read_1(iot, ioh, CL_TFTC) != 0)
        !          1039:                        bus_space_write_1(iot, ioh, CL_TDR, c);
        !          1040:        }
        !          1041:        bus_space_write_1(iot, ioh, CL_CAR, oldchannel);
        !          1042:        splx(s);
        !          1043: }
        !          1044:
        !          1045: int
        !          1046: clccparam(sc, par, channel)
        !          1047:        struct clsoftc *sc;
        !          1048:        struct termios *par;
        !          1049:        int channel;
        !          1050: {
        !          1051:        bus_space_tag_t iot;
        !          1052:        bus_space_handle_t ioh;
        !          1053:        u_int divisor, clk, clen;
        !          1054:        int s, imask, ints;
        !          1055:
        !          1056:        iot = sc->sc_iot;
        !          1057:        ioh = sc->sc_ioh;
        !          1058:
        !          1059:        s = splcl();
        !          1060:        bus_space_write_1(iot, ioh, CL_CAR, channel);
        !          1061:        if (par->c_ospeed == 0) {
        !          1062:                /* dont kill the console */
        !          1063:                if (sc->sc_cl[channel].cl_consio == 0) {
        !          1064:                        /* disconnect, drop RTS DTR stop receiver */
        !          1065:                        bus_space_write_1(iot, ioh, CL_MSVR_RTS, 0x00);
        !          1066:                        bus_space_write_1(iot, ioh, CL_MSVR_DTR, 0x00);
        !          1067:                        bus_space_write_1(iot, ioh, CL_CCR, 0x05);
        !          1068:                }
        !          1069:                splx(s);
        !          1070:                return 0xff;
        !          1071:        }
        !          1072:
        !          1073:        bus_space_write_1(iot, ioh, CL_MSVR_RTS, 0x03);
        !          1074:        bus_space_write_1(iot, ioh, CL_MSVR_DTR, 0x03);
        !          1075:
        !          1076:        divisor = cl_clkdiv(par->c_ospeed);
        !          1077:        clk     = cl_clknum(par->c_ospeed);
        !          1078:        bus_space_write_1(iot, ioh, CL_TBPR, divisor);
        !          1079:        bus_space_write_1(iot, ioh, CL_TCOR, clk << 5);
        !          1080:        divisor = cl_clkdiv(par->c_ispeed);
        !          1081:        clk     = cl_clknum(par->c_ispeed);
        !          1082:        bus_space_write_1(iot, ioh, CL_RBPR, divisor);
        !          1083:        bus_space_write_1(iot, ioh, CL_RCOR, clk);
        !          1084:        bus_space_write_1(iot, ioh, CL_RTPRL, cl_clkrxtimeout(par->c_ispeed));
        !          1085:        bus_space_write_1(iot, ioh, CL_RTPRH, 0x00);
        !          1086:
        !          1087:        switch (par->c_cflag & CSIZE) {
        !          1088:        case CS5:
        !          1089:                clen = 4; /* this is the mask for the chip. */
        !          1090:                imask = 0x1F;
        !          1091:                break;
        !          1092:        case CS6:
        !          1093:                clen = 5;
        !          1094:                imask = 0x3F;
        !          1095:                break;
        !          1096:        case CS7:
        !          1097:                clen = 6;
        !          1098:                imask = 0x7F;
        !          1099:                break;
        !          1100:        default:
        !          1101:                clen = 7;
        !          1102:                imask = 0xFF;
        !          1103:        }
        !          1104:
        !          1105:        bus_space_write_1(iot, ioh, CL_COR3, par->c_cflag & PARENB ? 4 : 2);
        !          1106:
        !          1107:        {
        !          1108:                u_int8_t cor1;
        !          1109:                if (par->c_cflag & PARENB) {
        !          1110:                        if (par->c_cflag & PARODD) {
        !          1111:                                cor1 = 0xE0 | clen ; /* odd */
        !          1112:                        } else {
        !          1113:                                cor1 = 0x40 | clen ; /* even */
        !          1114:                        }
        !          1115:                } else {
        !          1116:                        cor1 = 0x10 | clen; /* ignore parity */
        !          1117:                }
        !          1118:
        !          1119:                if (bus_space_read_1(iot, ioh, CL_COR1) != cor1) {
        !          1120:                        bus_space_write_1(iot, ioh, CL_COR1, cor1);
        !          1121:                        bus_space_write_1(iot, ioh, CL_CCR, 0x20);
        !          1122:                        while (bus_space_read_1(iot, ioh, CL_CCR) != 0)
        !          1123:                                ;
        !          1124:                }
        !          1125:        }
        !          1126:
        !          1127:        if (sc->sc_cl[channel].cl_consio == 0 && (par->c_cflag & CREAD) == 0)
        !          1128:                bus_space_write_1(iot, ioh, CL_CCR, 0x08);
        !          1129:        else
        !          1130:                bus_space_write_1(iot, ioh, CL_CCR, 0x0a);
        !          1131:
        !          1132:        while (bus_space_read_1(iot, ioh, CL_CCR) != 0)
        !          1133:                ;
        !          1134:
        !          1135:        ints = 0;
        !          1136: #define SCC_DSR 0x80
        !          1137: #define SCC_DCD 0x40
        !          1138: #define SCC_CTS 0x20
        !          1139:        if ((par->c_cflag & CLOCAL) == 0) {
        !          1140:                ints |= SCC_DCD;
        !          1141:        }
        !          1142:        if ((par->c_cflag & CCTS_OFLOW) != 0) {
        !          1143:                ints |= SCC_CTS;
        !          1144:        }
        !          1145:        if ((par->c_cflag & CRTSCTS) != 0) {
        !          1146:                ints |= SCC_CTS;
        !          1147:        }
        !          1148: #ifdef DONT_LET_HARDWARE
        !          1149:        if ((par->c_cflag & CCTS_IFLOW) != 0) {
        !          1150:                ints |= SCC_DSR;
        !          1151:        }
        !          1152: #endif
        !          1153:        bus_space_write_1(iot, ioh, CL_COR4, ints | CL_FIFO_CNT);
        !          1154:        bus_space_write_1(iot, ioh, CL_COR5, ints | CL_FIFO_CNT);
        !          1155:
        !          1156:        splx(s);
        !          1157:
        !          1158:        return imask;
        !          1159: }
        !          1160:
        !          1161: static int clknum = 0;
        !          1162:
        !          1163: u_int8_t
        !          1164: cl_clkdiv(speed)
        !          1165:        int speed;
        !          1166: {
        !          1167:        int i;
        !          1168:
        !          1169:        if (cl_clocks[clknum].speed == speed)
        !          1170:                return cl_clocks[clknum].divisor;
        !          1171:
        !          1172:        for  (i = 0; cl_clocks[i].speed != 0; i++) {
        !          1173:                if (cl_clocks[i].speed == speed) {
        !          1174:                        clknum = i;
        !          1175:                        return cl_clocks[clknum].divisor;
        !          1176:                }
        !          1177:        }
        !          1178:
        !          1179:        /* return some sane value if unknown speed */
        !          1180:        return cl_clocks[CL_SAFE_CLOCK].divisor;
        !          1181: }
        !          1182:
        !          1183: u_int8_t
        !          1184: cl_clknum(speed)
        !          1185:        int speed;
        !          1186: {
        !          1187:        int i;
        !          1188:
        !          1189:        if (cl_clocks[clknum].speed == speed)
        !          1190:                return cl_clocks[clknum].clock;
        !          1191:
        !          1192:        for (i = 0; cl_clocks[i].speed != 0; i++) {
        !          1193:                if (cl_clocks[clknum].speed == speed) {
        !          1194:                        clknum = i;
        !          1195:                        return cl_clocks[clknum].clock;
        !          1196:                }
        !          1197:        }
        !          1198:
        !          1199:        /* return some sane value if unknown speed */
        !          1200:        return cl_clocks[CL_SAFE_CLOCK].clock;
        !          1201: }
        !          1202:
        !          1203: u_int8_t
        !          1204: cl_clkrxtimeout(speed)
        !          1205:        int speed;
        !          1206: {
        !          1207:        int i;
        !          1208:
        !          1209:        if (cl_clocks[clknum].speed == speed)
        !          1210:                return cl_clocks[clknum].rx_timeout;
        !          1211:
        !          1212:        for  (i = 0; cl_clocks[i].speed != 0; i++) {
        !          1213:                if (cl_clocks[i].speed == speed) {
        !          1214:                        clknum = i;
        !          1215:                        return cl_clocks[clknum].rx_timeout;
        !          1216:                }
        !          1217:        }
        !          1218:
        !          1219:        /* return some sane value if unknown speed */
        !          1220:        return cl_clocks[CL_SAFE_CLOCK].rx_timeout;
        !          1221: }
        !          1222:
        !          1223: void
        !          1224: cl_unblock(tp)
        !          1225:        struct tty *tp;
        !          1226: {
        !          1227:        tp->t_state &= ~TS_FLUSH;
        !          1228:        if (tp->t_outq.c_cc != 0)
        !          1229:                clstart(tp);
        !          1230: }
        !          1231:
        !          1232: void
        !          1233: clstart(tp)
        !          1234:        struct tty *tp;
        !          1235: {
        !          1236:        dev_t dev;
        !          1237:        struct clsoftc *sc;
        !          1238:        int channel, unit, s;
        !          1239: #if 0
        !          1240:        int cnt;
        !          1241:        u_int8_t cbuf;
        !          1242: #endif
        !          1243:
        !          1244:        dev = tp->t_dev;
        !          1245:        channel = CL_CHANNEL(dev);
        !          1246: /* hack to test output on non console only */
        !          1247: #if 0
        !          1248:        if (channel == 0) {
        !          1249:                cloutput(tp);
        !          1250:                return;
        !          1251:        }
        !          1252: #endif
        !          1253:        unit = CL_UNIT(dev);
        !          1254:        if (unit >= cl_cd.cd_ndevs ||
        !          1255:            (sc = (struct clsoftc *)cl_cd.cd_devs[unit]) == NULL) {
        !          1256:                return;
        !          1257:        }
        !          1258:
        !          1259:        if ((tp->t_state & TS_ISOPEN) == 0)
        !          1260:                return;
        !          1261:
        !          1262:        s = splcl();
        !          1263: #if 0
        !          1264:        if (sc->sc_cl[channel].transmitting == 1) {
        !          1265:                /* i'm busy, go away, I will get to it later. */
        !          1266:                splx(s);
        !          1267:                return;
        !          1268:        }
        !          1269:        cnt = q_to_b(&tp->t_outq, &cbuf, 1);
        !          1270:        if ( cnt != 0 ) {
        !          1271:                sc->sc_cl[channel].transmitting = 1;
        !          1272:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, CL_CAR, channel);
        !          1273:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, CL_TDR, cbuf);
        !          1274:        } else {
        !          1275:                sc->sc_cl[channel].transmitting = 0;
        !          1276:        }
        !          1277: #else
        !          1278:        if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP | TS_FLUSH)) == 0)
        !          1279:        {
        !          1280:                tp->t_state |= TS_BUSY;
        !          1281:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, CL_CAR, channel);
        !          1282:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, CL_IER,
        !          1283:                    bus_space_read_1(sc->sc_iot, sc->sc_ioh, CL_IER) | 0x03);
        !          1284:        }
        !          1285: #endif
        !          1286:        splx(s);
        !          1287: }
        !          1288:
        !          1289: int
        !          1290: cl_mintr(arg)
        !          1291:        void *arg;
        !          1292: {
        !          1293:        struct clsoftc *sc = arg;
        !          1294:        bus_space_tag_t iot;
        !          1295:        bus_space_handle_t ioh;
        !          1296:        u_int8_t mir, misr, msvr;
        !          1297:        int channel;
        !          1298:
        !          1299:        iot = sc->sc_iot;
        !          1300:        ioh = sc->sc_ioh;
        !          1301:
        !          1302:        mir = bus_space_read_1(iot, ioh, CL_MIR);
        !          1303:        if ((mir & 0x40) == 0) {
        !          1304:                return 0;
        !          1305:        }
        !          1306:
        !          1307:        channel = mir & 0x03;
        !          1308:        misr = bus_space_read_1(iot, ioh, CL_MISR);
        !          1309:        msvr = bus_space_read_1(iot, ioh, CL_MSVR_RTS);
        !          1310:        if (misr & 0x01) {
        !          1311:                /* timers are not currently used?? */
        !          1312:                log(LOG_WARNING, "cl_mintr: channel %x timer 1 unexpected\n",channel);
        !          1313:        }
        !          1314:        if (misr & 0x02) {
        !          1315:                /* timers are not currently used?? */
        !          1316:                log(LOG_WARNING, "cl_mintr: channel %x timer 2 unexpected\n",channel);
        !          1317:        }
        !          1318:        if (misr & 0x20) {
        !          1319: #ifdef DEBUG
        !          1320:                log(LOG_WARNING, "cl_mintr: channel %x cts %x\n",channel,
        !          1321:                    ((msvr & 0x20) != 0x0)
        !          1322:                );
        !          1323: #endif
        !          1324:        }
        !          1325:        if (misr & 0x40) {
        !          1326:                struct tty *tp = sc->sc_cl[channel].tty;
        !          1327: #ifdef DEBUG
        !          1328:                log(LOG_WARNING, "cl_mintr: channel %x cd %x\n",channel,
        !          1329:                    ((msvr & 0x40) != 0x0)
        !          1330:                );
        !          1331: #endif
        !          1332:                ttymodem(tp, ((msvr & 0x40) != 0x0) );
        !          1333:        }
        !          1334:        if (misr & 0x80) {
        !          1335: #ifdef DEBUG
        !          1336:                log(LOG_WARNING, "cl_mintr: channel %x dsr %x\n",channel,
        !          1337:                ((msvr & 0x80) != 0x0)
        !          1338:                );
        !          1339: #endif
        !          1340:        }
        !          1341:        bus_space_write_1(iot, ioh, CL_MEOIR, 0);
        !          1342:        return 1;
        !          1343: }
        !          1344:
        !          1345: int
        !          1346: cl_txintr(arg)
        !          1347:        void *arg;
        !          1348: {
        !          1349:        static int empty;
        !          1350:        struct clsoftc *sc = arg;
        !          1351:        bus_space_tag_t iot;
        !          1352:        bus_space_handle_t ioh;
        !          1353:        u_int8_t tir, cmr, teoir;
        !          1354:        u_int8_t max;
        !          1355:        int channel;
        !          1356:        struct tty *tp;
        !          1357:        int cnt;
        !          1358:        u_char buffer[CL_FIFO_MAX +1];
        !          1359:
        !          1360:        iot = sc->sc_iot;
        !          1361:        ioh = sc->sc_ioh;
        !          1362:        tir = bus_space_read_1(iot, ioh, CL_TIR);
        !          1363:        if ((tir & 0x40) == 0) {
        !          1364:                return 0;
        !          1365:        }
        !          1366:
        !          1367:        channel = tir & 0x03;
        !          1368:        sc->sc_cl[channel].txcnt ++;
        !          1369:
        !          1370:        cmr = bus_space_read_1(iot, ioh, CL_CMR);
        !          1371:
        !          1372:        tp = sc->sc_cl[channel].tty;
        !          1373:        if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) {
        !          1374:                bus_space_write_1(iot, ioh, CL_IER,
        !          1375:                    bus_space_read_1(iot, ioh, CL_IER) & ~0x03);
        !          1376:                bus_space_write_1(iot, ioh, CL_TEOIR, 0x08);
        !          1377:                return 1;
        !          1378:        }
        !          1379:
        !          1380:        switch (cmr & CL_TXMASK) {
        !          1381:        case CL_TXDMAINT:
        !          1382:        {
        !          1383:                u_int8_t dmabsts;
        !          1384:                int nbuf, busy, resid;
        !          1385:                void *pbuffer;
        !          1386:
        !          1387:                dmabsts = bus_space_read_1(iot, ioh, CL_DMABSTS);
        !          1388:                nbuf = ((dmabsts & 0x8) >> 3) & 0x1;
        !          1389:                busy = ((dmabsts & 0x4) >> 2) & 0x1;
        !          1390:
        !          1391:                do {
        !          1392:                        pbuffer = sc->sc_cl[channel].tx[nbuf];
        !          1393:                        resid = tp->t_outq.c_cc;
        !          1394:                        cnt = min (CL_BUFSIZE,resid);
        !          1395:                        log(LOG_WARNING, "cl_txintr: resid %x cnt %x pbuf %p\n",
        !          1396:                            resid, cnt, pbuffer);
        !          1397:                        if (cnt != 0) {
        !          1398:                                cnt = q_to_b(&tp->t_outq, pbuffer, cnt);
        !          1399:                                resid -= cnt;
        !          1400:                                if (nbuf == 0) {
        !          1401:                                        bus_space_write_2(iot, ioh, CL_ATBADRU,
        !          1402:                                            ((u_long)sc->sc_cl[channel].txp[nbuf]) >> 16);
        !          1403:                                        bus_space_write_2(iot, ioh, CL_ATBADRL,
        !          1404:                                            ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff);
        !          1405:                                        bus_space_write_2(iot, ioh, CL_ATBCNT,
        !          1406:                                            cnt);
        !          1407:                                        bus_space_write_1(iot, ioh, CL_ATBSTS,
        !          1408:                                            0x43);
        !          1409:                                } else {
        !          1410:                                        bus_space_write_2(iot, ioh, CL_BTBADRU,
        !          1411:                                            ((u_long)sc->sc_cl[channel].txp[nbuf]) >> 16);
        !          1412:                                        bus_space_write_2(iot, ioh, CL_BTBADRL,
        !          1413:                                            ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff);
        !          1414:                                        bus_space_write_2(iot, ioh, CL_BTBCNT,
        !          1415:                                            cnt);
        !          1416:                                        bus_space_write_1(iot, ioh, CL_BTBSTS,
        !          1417:                                            0x43);
        !          1418:                                }
        !          1419:                                teoir = 0x08;
        !          1420:                        } else {
        !          1421:                                teoir = 0x08;
        !          1422:                                if (tp->t_state & TS_BUSY) {
        !          1423:                                        tp->t_state &= ~(TS_BUSY | TS_FLUSH);
        !          1424:                                        if (tp->t_state & TS_ASLEEP) {
        !          1425:                                                tp->t_state &= ~TS_ASLEEP;
        !          1426:                                                wakeup((caddr_t) &tp->t_outq);
        !          1427:                                        }
        !          1428:                                        selwakeup(&tp->t_wsel);
        !          1429:                                }
        !          1430:                                bus_space_write_1(iot, ioh, CL_IER,
        !          1431:                                    bus_space_read_1(iot, ioh, CL_IER) & ~0x03);
        !          1432:                        }
        !          1433:                        nbuf = ~nbuf & 0x1;
        !          1434:                        busy--;
        !          1435:                } while (resid != 0 && busy != -1);/* if not busy do other buffer */
        !          1436:        }
        !          1437:                break;
        !          1438:        case CL_TXINTR:
        !          1439:                max = bus_space_read_1(iot, ioh, CL_TFTC);
        !          1440:                cnt = min((int)max,tp->t_outq.c_cc);
        !          1441:                if (cnt != 0) {
        !          1442:                        cnt = q_to_b(&tp->t_outq, buffer, cnt);
        !          1443:                        empty = 0;
        !          1444:                        bus_space_write_multi_1(iot, ioh, CL_TDR, buffer, cnt);
        !          1445:                        teoir = 0x00;
        !          1446:                } else {
        !          1447:                        if (empty > 5 && ((empty % 20000 )== 0)) {
        !          1448:                                log(LOG_WARNING, "cl_txintr to many empty intr %d channel %d\n",
        !          1449:                                    empty, channel);
        !          1450:                        }
        !          1451:                        empty++;
        !          1452:                        teoir = 0x08;
        !          1453:                        if (tp->t_state & TS_BUSY) {
        !          1454:                                tp->t_state &= ~(TS_BUSY | TS_FLUSH);
        !          1455:                                if (tp->t_state & TS_ASLEEP) {
        !          1456:                                        tp->t_state &= ~TS_ASLEEP;
        !          1457:                                        wakeup((caddr_t) &tp->t_outq);
        !          1458:                                }
        !          1459:                                selwakeup(&tp->t_wsel);
        !          1460:                        }
        !          1461:                        bus_space_write_1(iot, ioh, CL_IER,
        !          1462:                            bus_space_read_1(iot, ioh, CL_IER) & ~0x03);
        !          1463:                }
        !          1464:                break;
        !          1465:        default:
        !          1466:                log(LOG_WARNING, "cl_txintr unknown mode %x\n", cmr);
        !          1467:                /* we probably will go to hell quickly now */
        !          1468:                teoir = 0x08;
        !          1469:        }
        !          1470:        bus_space_write_1(iot, ioh, CL_TEOIR, teoir);
        !          1471:        return 1;
        !          1472: }
        !          1473:
        !          1474: int
        !          1475: cl_rxintr(arg)
        !          1476:        void *arg;
        !          1477: {
        !          1478:        struct clsoftc *sc = arg;
        !          1479:        bus_space_tag_t iot;
        !          1480:        bus_space_handle_t ioh;
        !          1481:        u_int8_t rir, channel, cmr, risrl;
        !          1482:        u_int8_t fifocnt;
        !          1483:        struct tty *tp;
        !          1484:        int i;
        !          1485:        u_int8_t reoir;
        !          1486:        u_char buffer[CL_FIFO_MAX +1];
        !          1487: #ifdef DDB
        !          1488:        int wantddb = 0;
        !          1489: #endif
        !          1490:
        !          1491:        iot = sc->sc_iot;
        !          1492:        ioh = sc->sc_ioh;
        !          1493:
        !          1494:        rir = bus_space_read_1(iot, ioh, CL_RIR);
        !          1495:        if ((rir & 0x40) == 0x0) {
        !          1496:                return 0;
        !          1497:        }
        !          1498:
        !          1499:        channel = rir & 0x3;
        !          1500:        cmr = bus_space_read_1(iot, ioh, CL_CMR);
        !          1501:
        !          1502:        sc->sc_cl[channel].rxcnt ++;
        !          1503:        risrl = bus_space_read_1(iot, ioh, CL_RISRL);
        !          1504:        if (risrl & 0x80) {
        !          1505:                /* timeout, no characters */
        !          1506:        } else
        !          1507:        /* We don't need no stinkin special characters */
        !          1508:        if (risrl & 0x08) {
        !          1509:                cl_overflow(sc, channel, (long *)&sc->sc_fotime, "fifo");
        !          1510:        } else
        !          1511:        if (risrl & 0x04) {
        !          1512:                cl_parity(sc, channel);
        !          1513:        } else
        !          1514:        if (risrl & 0x02) {
        !          1515:                cl_frame(sc, channel);
        !          1516:        } else
        !          1517:        if (risrl & 0x01) {
        !          1518: #ifdef DDB
        !          1519:                if (sc->sc_cl[channel].cl_consio)
        !          1520:                        wantddb = db_console;
        !          1521: #endif
        !          1522:                cl_break(sc, channel);
        !          1523:        }
        !          1524:        reoir = 0x08;
        !          1525:
        !          1526:        switch (cmr & CL_RXMASK) {
        !          1527:        case CL_RXDMAINT:
        !          1528:        {
        !          1529:                int nbuf;
        !          1530:                u_int16_t cnt;
        !          1531:                int bufcomplete;
        !          1532:                u_int8_t status, dmabsts;
        !          1533:                u_int8_t risrh;
        !          1534:
        !          1535:                risrh = bus_space_read_1(iot, ioh, CL_RISRH);
        !          1536:                dmabsts = bus_space_read_1(iot, ioh, CL_DMABSTS);
        !          1537:                nbuf = (risrh & 0x08) ? 1 : 0;
        !          1538:                bufcomplete = (risrh & 0x20) ? 1 : 0;
        !          1539:                if (nbuf == 0) {
        !          1540:                        cnt = bus_space_read_2(iot, ioh, CL_ARBCNT);
        !          1541:                        status = bus_space_read_1(iot, ioh, CL_ARBSTS);
        !          1542:                } else {
        !          1543:                        cnt = bus_space_read_2(iot, ioh, CL_BRBCNT);
        !          1544:                        status = bus_space_read_1(iot, ioh, CL_BRBSTS);
        !          1545:                }
        !          1546: #if USE_BUFFER
        !          1547:                cl_appendbufn(sc, channel, sc->rx[nbuf], cnt);
        !          1548: #else
        !          1549:                {
        !          1550:                        int i;
        !          1551:                        u_char *pbuf;
        !          1552:
        !          1553:                        tp = sc->sc_cl[channel].tty;
        !          1554:                        pbuf = sc->sc_cl[channel].rx[nbuf];
        !          1555:                        /* this should be done at off level */
        !          1556:                        {
        !          1557:                                u_int16_t rcbadru, rcbadrl;
        !          1558:                                u_int8_t arbsts, brbsts;
        !          1559:                                u_char *pbufs, *pbufe;
        !          1560:
        !          1561:                                rcbadru = bus_space_read_2(iot, ioh,
        !          1562:                                    CL_RCBADRU);
        !          1563:                                rcbadrl = bus_space_read_2(iot, ioh,
        !          1564:                                    CL_RCBADRL);
        !          1565:                                arbsts = bus_space_read_1(iot, ioh, CL_ARBSTS);
        !          1566:                                brbsts = bus_space_read_1(iot, ioh, CL_BRBSTS);
        !          1567:                                pbufs = sc->sc_cl[channel].rxp[nbuf];
        !          1568:                                pbufe = (u_char *)(((u_long)rcbadru << 16) | (u_long)rcbadrl);
        !          1569:                                cnt = pbufe - pbufs;
        !          1570:                        }
        !          1571:                        reoir = 0x0 | (bufcomplete) ? 0 : 0xd0;
        !          1572:                        bus_space_write_1(iot, ioh, CL_REOIR, reoir);
        !          1573:
        !          1574:                        DELAY(10); /* give the chip a moment */
        !          1575:
        !          1576:                        for (i = 0; i < cnt; i++) {
        !          1577:                                u_char c;
        !          1578:                                c = pbuf[i];
        !          1579:                                (*linesw[tp->t_line].l_rint)(c,tp);
        !          1580:                        }
        !          1581:                        /* this should be done at off level */
        !          1582:                        if (nbuf == 0) {
        !          1583:                                bus_space_write_2(iot, ioh, CL_ARBCNT,
        !          1584:                                    CL_BUFSIZE);
        !          1585:                                bus_space_write_2(iot, ioh, CL_ARBSTS, 0x01);
        !          1586:                        } else {
        !          1587:                                bus_space_write_2(iot, ioh, CL_BRBCNT,
        !          1588:                                    CL_BUFSIZE);
        !          1589:                                bus_space_write_2(iot, ioh, CL_BRBSTS, 0x01);
        !          1590:                        }
        !          1591:                }
        !          1592: #endif
        !          1593:        }
        !          1594:                bus_space_write_1(iot, ioh, CL_REOIR, reoir);
        !          1595:                break;
        !          1596:        case CL_RXINTR:
        !          1597:                fifocnt = bus_space_read_1(iot, ioh, CL_RFOC);
        !          1598:                tp = sc->sc_cl[channel].tty;
        !          1599:                bus_space_read_multi_1(iot, ioh, CL_RDR, buffer, fifocnt);
        !          1600:                if (tp == NULL) {
        !          1601:                        /* if the channel is not configured,
        !          1602:                         * dont send characters upstream.
        !          1603:                         * also fix problem with NULL dereference
        !          1604:                         */
        !          1605:                        reoir = 0x00;
        !          1606:                        break;
        !          1607:                }
        !          1608:
        !          1609:                bus_space_write_1(iot, ioh, CL_REOIR, reoir);
        !          1610:                for (i = 0; i < fifocnt; i++) {
        !          1611:                        u_char c;
        !          1612:                        c = buffer[i];
        !          1613: #if USE_BUFFER
        !          1614:                        cl_appendbuf(sc, channel, c);
        !          1615: #else
        !          1616:                        /* does any restricitions exist on spl
        !          1617:                         * for this call
        !          1618:                         */
        !          1619:                        (*linesw[tp->t_line].l_rint)(c,tp);
        !          1620: #endif
        !          1621:                }
        !          1622:                break;
        !          1623:        default:
        !          1624:                log(LOG_WARNING, "cl_rxintr unknown mode %x\n", cmr);
        !          1625:                /* we probably will go to hell quickly now */
        !          1626:                bus_space_write_1(iot, ioh, CL_REOIR, 0x08);
        !          1627:        }
        !          1628: #ifdef DDB
        !          1629:        if (wantddb != 0)
        !          1630:                Debugger();
        !          1631: #endif
        !          1632:        return 1;
        !          1633: }
        !          1634:
        !          1635: void
        !          1636: cl_overflow(sc, channel, ptime, msg)
        !          1637:        struct clsoftc *sc;
        !          1638:        int channel;
        !          1639:        long *ptime;
        !          1640:        char *msg;
        !          1641: {
        !          1642:        log(LOG_WARNING, "%s[%d]: %s overrun\n", sc->sc_dev.dv_xname,
        !          1643:            channel, msg);
        !          1644: }
        !          1645:
        !          1646: void
        !          1647: cl_parity(sc, channel)
        !          1648:        struct clsoftc *sc;
        !          1649:        int channel;
        !          1650: {
        !          1651:        log(LOG_WARNING, "%s[%d]: parity error\n", sc->sc_dev.dv_xname,
        !          1652:            channel);
        !          1653: }
        !          1654:
        !          1655: void
        !          1656: cl_frame(sc, channel)
        !          1657:        struct clsoftc *sc;
        !          1658:        int channel;
        !          1659: {
        !          1660:        log(LOG_WARNING, "%s[%d]: frame error\n", sc->sc_dev.dv_xname,
        !          1661:            channel);
        !          1662: }
        !          1663:
        !          1664: void
        !          1665: cl_break(sc, channel)
        !          1666:        struct clsoftc *sc;
        !          1667:        int channel;
        !          1668: {
        !          1669: #ifdef DEBUG
        !          1670:        log(LOG_WARNING, "%s[%d]: break detected\n", sc->sc_dev.dv_xname,
        !          1671:            channel);
        !          1672: #endif
        !          1673: }
        !          1674:
        !          1675: #ifdef DEBUG
        !          1676: void
        !          1677: cl_dumpport(struct clsoftc *sc, int channel)
        !          1678: {
        !          1679:        bus_space_tag_t iot;
        !          1680:        bus_space_handle_t ioh;
        !          1681:        u_int8_t livr, cmr, cor1, cor2, cor3, cor4, cor5, cor6, cor7,
        !          1682:            schr1, schr2, schr3, schr4, scrl, scrh, lnxt,
        !          1683:            rbpr, rcor, tbpr, tcor, rpilr, rir, tpr, ier, ccr,
        !          1684:            dmabsts, arbsts, brbsts, atbsts, btbsts,
        !          1685:            csr, rts, dtr, rtprl, rtprh;
        !          1686:        u_int16_t rcbadru, rcbadrl, arbadru, arbadrl, arbcnt,
        !          1687:            brbadru, brbadrl, brbcnt;
        !          1688:        u_int16_t tcbadru, tcbadrl, atbadru, atbadrl, atbcnt,
        !          1689:            btbadru, btbadrl, btbcnt;
        !          1690:        int s;
        !          1691:
        !          1692:        iot = sc->sc_iot;
        !          1693:        ioh = sc->sc_ioh;
        !          1694:
        !          1695:        s = splcl();
        !          1696:        bus_space_write_1(iot, ioh, CL_CAR, channel);
        !          1697:        livr = bus_space_read_1(iot, ioh, CL_LIVR);
        !          1698:        cmr = bus_space_read_1(iot, ioh, CL_CMR);
        !          1699:        cor1 = bus_space_read_1(iot, ioh, CL_COR1);
        !          1700:        cor2 = bus_space_read_1(iot, ioh, CL_COR2);
        !          1701:        cor3 = bus_space_read_1(iot, ioh, CL_COR3);
        !          1702:        cor4 = bus_space_read_1(iot, ioh, CL_COR4);
        !          1703:        cor5 = bus_space_read_1(iot, ioh, CL_COR5);
        !          1704:        cor6 = bus_space_read_1(iot, ioh, CL_COR6);
        !          1705:        cor7 = bus_space_read_1(iot, ioh, CL_COR7);
        !          1706:        schr1 = bus_space_read_1(iot, ioh, CL_SCHR1);
        !          1707:        schr2 = bus_space_read_1(iot, ioh, CL_SCHR2);
        !          1708:        schr3 = bus_space_read_1(iot, ioh, CL_SCHR3);
        !          1709:        schr4 = bus_space_read_1(iot, ioh, CL_SCHR4);
        !          1710:        scrl = bus_space_read_1(iot, ioh, CL_SCRL);
        !          1711:        scrh = bus_space_read_1(iot, ioh, CL_SCRH);
        !          1712:        lnxt = bus_space_read_1(iot, ioh, CL_LNXT);
        !          1713:        rbpr = bus_space_read_1(iot, ioh, CL_RBPR);
        !          1714:        rcor = bus_space_read_1(iot, ioh, CL_RCOR);
        !          1715:        tbpr = bus_space_read_1(iot, ioh, CL_TBPR);
        !          1716:        rpilr = bus_space_read_1(iot, ioh, CL_RPILR);
        !          1717:        rir = bus_space_read_1(iot, ioh, CL_RIR);
        !          1718:        ier = bus_space_read_1(iot, ioh, CL_IER);
        !          1719:        ccr = bus_space_read_1(iot, ioh, CL_CCR);
        !          1720:        tcor = bus_space_read_1(iot, ioh, CL_TCOR);
        !          1721:        csr = bus_space_read_1(iot, ioh, CL_CSR);
        !          1722:        tpr = bus_space_read_1(iot, ioh, CL_TPR);
        !          1723:        rts = bus_space_read_1(iot, ioh, CL_MSVR_RTS);
        !          1724:        dtr = bus_space_read_1(iot, ioh, CL_MSVR_DTR);
        !          1725:        rtprl = bus_space_read_1(iot, ioh, CL_RTPRL);
        !          1726:        rtprh = bus_space_read_1(iot, ioh, CL_RTPRH);
        !          1727:        dmabsts = bus_space_read_1(iot, ioh, CL_DMABSTS);
        !          1728:        tcbadru = bus_space_read_2(iot, ioh, CL_TCBADRU);
        !          1729:        tcbadrl = bus_space_read_2(iot, ioh, CL_TCBADRL);
        !          1730:        rcbadru = bus_space_read_2(iot, ioh, CL_RCBADRU);
        !          1731:        rcbadrl = bus_space_read_2(iot, ioh, CL_RCBADRL);
        !          1732:        arbadru = bus_space_read_2(iot, ioh, CL_ARBADRU);
        !          1733:        arbadrl = bus_space_read_2(iot, ioh, CL_ARBADRL);
        !          1734:        arbcnt  = bus_space_read_2(iot, ioh, CL_ARBCNT);
        !          1735:        arbsts  = bus_space_read_1(iot, ioh, CL_ARBSTS);
        !          1736:        brbadru = bus_space_read_2(iot, ioh, CL_BRBADRU);
        !          1737:        brbadrl = bus_space_read_2(iot, ioh, CL_BRBADRL);
        !          1738:        brbcnt  = bus_space_read_2(iot, ioh, CL_BRBCNT);
        !          1739:        brbsts  = bus_space_read_1(iot, ioh, CL_BRBSTS);
        !          1740:        atbadru = bus_space_read_2(iot, ioh, CL_ATBADRU);
        !          1741:        atbadrl = bus_space_read_2(iot, ioh, CL_ATBADRL);
        !          1742:        atbcnt  = bus_space_read_2(iot, ioh, CL_ATBCNT);
        !          1743:        atbsts  = bus_space_read_1(iot, ioh, CL_ATBSTS);
        !          1744:        btbadru = bus_space_read_2(iot, ioh, CL_BTBADRU);
        !          1745:        btbadrl = bus_space_read_2(iot, ioh, CL_BTBADRL);
        !          1746:        btbcnt  = bus_space_read_2(iot, ioh, CL_BTBCNT);
        !          1747:        btbsts  = bus_space_read_1(iot, ioh, CL_BTBSTS);
        !          1748:        splx(s);
        !          1749:
        !          1750:        printf("{ port %x livr %x cmr %x\n",
        !          1751:                  channel,livr,   cmr);
        !          1752:        printf("cor1 %x cor2 %x cor3 %x cor4 %x cor5 %x cor6 %x cor7 %x\n",
        !          1753:                cor1,   cor2,   cor3,   cor4,   cor5,   cor6,   cor7);
        !          1754:        printf("schr1 %x schr2 %x schr3 %x schr4 %x\n",
        !          1755:                schr1,   schr2,   schr3,   schr4);
        !          1756:        printf("scrl %x scrh %x lnxt %x\n",
        !          1757:                scrl,   scrh,   lnxt);
        !          1758:        printf("rbpr %x rcor %x tbpr %x tcor %x\n",
        !          1759:                rbpr,   rcor,   tbpr,   tcor);
        !          1760:        printf("rpilr %x rir %x ier %x ccr %x\n",
        !          1761:                rpilr,   rir,   ier,   ccr);
        !          1762:        printf("tpr %x csr %x rts %x dtr %x\n",
        !          1763:                tpr,   csr,   rts,   dtr);
        !          1764:        printf("rtprl %x rtprh %x\n",
        !          1765:                rtprl,   rtprh);
        !          1766:        printf("rxcnt %x txcnt %x\n",
        !          1767:                sc->sc_cl[channel].rxcnt, sc->sc_cl[channel].txcnt);
        !          1768:        printf("dmabsts %x, tcbadru %x, tcbadrl %x, rcbadru %x, rcbadrl %x,\n",
        !          1769:                dmabsts,    tcbadru,    tcbadrl,    rcbadru,    rcbadrl );
        !          1770:        printf("arbadru %x, arbadrl %x, arbcnt %x, arbsts %x\n",
        !          1771:                arbadru,    arbadrl,    arbcnt,    arbsts);
        !          1772:        printf("brbadru %x, brbadrl %x, brbcnt %x, brbsts %x\n",
        !          1773:                brbadru,    brbadrl,    brbcnt,    brbsts);
        !          1774:        printf("atbadru %x, atbadrl %x, atbcnt %x, atbsts %x\n",
        !          1775:                atbadru,    atbadrl,    atbcnt,    atbsts);
        !          1776:        printf("btbadru %x, btbadrl %x, btbcnt %x, btbsts %x\n",
        !          1777:                btbadru,    btbadrl,    btbcnt,    btbsts);
        !          1778:        printf("}\n");
        !          1779: }
        !          1780: #endif

CVSweb