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

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

1.1       nbrk        1: /*     $OpenBSD: wl.c,v 1.18 2005/11/24 22:43:16 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: #include <sys/param.h>
                     28: #include <sys/ioctl.h>
                     29: #include <sys/proc.h>
                     30: #include <sys/tty.h>
                     31: #include <sys/uio.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/time.h>
                     34: #include <sys/device.h>
                     35: #include <sys/syslog.h>
                     36:
                     37: #include <machine/autoconf.h>
                     38: #include <machine/conf.h>
                     39: #include <machine/cpu.h>
                     40:
                     41: #include <mvme68k/dev/wlreg.h>
                     42: #include <mvme68k/dev/vme.h>
                     43:
                     44: #include "cl.h"
                     45:
                     46: #include "vmes.h"
                     47:
                     48: #define splcl() spltty()
                     49:
                     50: /* min timeout 0xa, what is a good value */
                     51: #define CL_TIMEOUT     0x10
                     52: #define CL_FIFO_MAX    0x10
                     53: #define CL_FIFO_CNT    0xc
                     54: #define        CL_RX_TIMEOUT   0x10
                     55:
                     56: #define CL_RXDMAINT    0x82
                     57: #define CL_TXDMAINT    0x42
                     58: #define CL_TXMASK      0x47
                     59: #define CL_RXMASK      0x87
                     60: #define CL_TXINTR      0x02
                     61: #define CL_RXINTR      0x02
                     62:
                     63: #define WLRAMLEN       (1 << 16)
                     64: struct clboard {
                     65:        union {
                     66:                struct clreg    clreg;
                     67:                volatile char           xx[256];
                     68:        } chips[2];
                     69:        union {
                     70:                volatile u_char         base;
                     71:                volatile char           xx[256];
                     72:        } sram;
                     73:        union {
                     74:                volatile u_char         val;
                     75:                volatile char           xx[256];
                     76:        } ringstatus;
                     77:        union {
                     78:                volatile u_char         val;
                     79:                volatile char           xx[256];
                     80:        } ringreset;
                     81:        union {
                     82:                volatile u_char         val;
                     83:                volatile char           xx[256];
                     84:        } master;
                     85:        union {
                     86:                volatile u_char         val;
                     87:                volatile char           xx[256];
                     88:        } reset;
                     89: };
                     90:
                     91:
                     92: struct cl_info {
                     93:        struct tty *tty;
                     94:        u_char  cl_swflags;
                     95:        u_char  cl_softchar;
                     96:        u_char  cl_speed;
                     97:        u_char  cl_parstop;     /* parity, stop bits. */
                     98:        u_char  cl_rxmode;
                     99:        u_char  cl_txmode;
                    100:        u_char  cl_clen;
                    101:        u_char  cl_parity;
                    102:        u_char  transmitting;
                    103:        u_long  txcnt;
                    104:        u_long  rxcnt;
                    105:
                    106:        volatile void   *rx[2];
                    107:        volatile void   *rxp[2];
                    108:        volatile void   *tx[2];
                    109:        volatile void   *txp[2];
                    110: };
                    111: #define CLCD_PORTS_PER_CHIP 4
                    112: #define CL_BUFSIZE 128
                    113:
                    114: struct wlsoftc {
                    115:        struct device   sc_dev;
                    116:        char            sc_txintrname[16 + 3];
                    117:        char            sc_rxintrname[16 + 3];
                    118:        char            sc_mxintrname[16 + 3];
                    119:
                    120:        time_t          sc_rotime;      /* time of last ring overrun */
                    121:        time_t          sc_fotime;      /* time of last fifo overrun */
                    122:
                    123:        u_char          sc_memv;
                    124:        paddr_t         sc_memvme;
                    125:        void            *sc_memp;
                    126:        vaddr_t         sc_memkv;
                    127:
                    128:        struct clreg    *cl_reg;
                    129:        struct cl_info  sc_cl[CLCD_PORTS_PER_CHIP];
                    130:        struct intrhand sc_ih_e;
                    131:        struct intrhand sc_ih_m;
                    132:        struct intrhand sc_ih_t;
                    133:        struct intrhand sc_ih_r;
                    134:        u_char          sc_vec;
                    135:        int             sc_flags;
                    136: };
                    137:
                    138: struct {
                    139:        u_int speed;
                    140:        u_char divisor;
                    141:        u_char clock;
                    142:        u_char rx_timeout;
                    143: } cl_clocks[] = {
                    144:        /* 30.000 MHz */
                    145:        {   64000, 0x3a, 0, 0x01 },
                    146:        {   56000, 0x42, 0, 0x01 },
                    147:        {   38400, 0x61, 0, 0x01 },
                    148:        {   19200, 0xc2, 0, 0x01 },
                    149:        {    9600, 0x61, 1, 0x02 },
                    150:        {    7200, 0x81, 1, 0x04 },
                    151:        {    4800, 0xc2, 1, 0x04 },
                    152:        {    3600, 0x40, 2, 0x08 },
                    153:        {    2400, 0x61, 2, 0x10 },
                    154:        {    1200, 0xc2, 2, 0x20 },
                    155:        {     600, 0x61, 3, 0x40 },
                    156:        {     300, 0xc2, 3, 0x80 },
                    157:        {     150, 0x61, 4, 0xa0 },
                    158:        {     110, 0x84, 4, 0xff },
                    159:        {      50, 0x00, 5, 0xff },
                    160:        {       0, 0x00, 0, 0},
                    161: };
                    162:
                    163: /* prototypes */
                    164: u_char cl_clkdiv(int speed);
                    165: u_char cl_clknum(int speed);
                    166: u_char cl_clkrxtimeout(int speed);
                    167: void clstart(struct tty *tp);
                    168: void cl_unblock(struct tty *tp);
                    169: int clccparam(struct wlsoftc *sc, struct termios *par, int channel);
                    170:
                    171: int clparam(struct tty *tp, struct termios *t);
                    172: int cl_intr(struct wlsoftc *sc, int);
                    173: int cl_mintr(struct wlsoftc *sc);
                    174: int cl_txintr(struct wlsoftc *sc);
                    175: int cl_rxintr(struct wlsoftc *sc);
                    176: void cl_overflow(struct wlsoftc *sc, int channel, long *ptime, u_char *msg);
                    177: void cl_parity(struct wlsoftc *sc, int channel);
                    178: void cl_frame(struct wlsoftc *sc, int channel);
                    179: void cl_break( struct wlsoftc *sc, int channel);
                    180: int clmctl(dev_t dev, int bits, int how);
                    181: void cl_dumpport(int channel);
                    182:
                    183: int    wlprobe(struct device *parent, void *self, void *aux);
                    184: void   wlattach(struct device *parent, struct device *self, void *aux);
                    185:
                    186: static void cl_initchannel(struct wlsoftc *sc, int channel);
                    187: static void clputc(struct wlsoftc *sc, int unit, u_char c);
                    188: static u_char clgetc(struct wlsoftc *sc, int *channel);
                    189: static void cloutput(struct tty *tp);
                    190:
                    191: struct cfattach wl_ca = {
                    192:        sizeof(struct wlsoftc), wlprobe, wlattach
                    193: };
                    194:
                    195: struct cfdriver wl_cd = {
                    196:        NULL, "wl", DV_TTY
                    197: };
                    198:
                    199: #define CLCDBUF 80
                    200:
                    201: #define CL_UNIT(x) (minor(x) >> 2)
                    202: #define CL_CHANNEL(x) (minor(x) & 3)
                    203: #define CL_TTY(x) (minor(x))
                    204:
                    205: extern int cputyp;
                    206:
                    207: struct tty *
                    208: wltty(dev)
                    209:        dev_t dev;
                    210: {
                    211:        int unit = CL_UNIT(dev);
                    212:        int channel;
                    213:        struct wlsoftc *sc;
                    214:
                    215:        if (unit >= wl_cd.cd_ndevs ||
                    216:            (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL)
                    217:                return (NULL);
                    218:        channel = CL_CHANNEL(dev);
                    219:        return sc->sc_cl[channel].tty;
                    220: }
                    221:
                    222: int
                    223: wlprobe(parent, self, aux)
                    224:        struct device *parent;
                    225:        void *self;
                    226:        void *aux;
                    227: {
                    228:        struct confargs *ca = aux;
                    229:        struct wlsoftc *sc = self;
                    230:        struct clreg *cl_reg = (struct clreg *)ca->ca_vaddr;
                    231:
                    232:        if (ca->ca_vec & 0x03) {
                    233:                printf("%s: bad vector\n", sc->sc_dev.dv_xname);
                    234:                return (0);
                    235:        }
                    236:        return (!badvaddr(&cl_reg->cl_gfrcr, 1));
                    237: }
                    238:
                    239: void
                    240: wlattach(parent, self, aux)
                    241:        struct device *parent;
                    242:        struct device *self;
                    243:        void *aux;
                    244: {
                    245:        struct wlsoftc *sc = (struct wlsoftc *)self;
                    246:        struct confargs *ca = aux;
                    247:        struct clboard *clb = (struct clboard *)ca->ca_vaddr;
                    248:        void *p;
                    249:        int i, j, s;
                    250:
                    251:        sc->cl_reg = (struct clreg *)&clb->chips[0].clreg;
                    252:        sc->sc_vec = ca->ca_vec;
                    253:
                    254:        sc->sc_memv = 0xa5 + 0;
                    255:        sc->sc_memvme = ((0xff00 + sc->sc_memv) << 16);
                    256:
                    257:        clb->reset.val = 0xff;          /* reset card */
                    258:        DELAY(1000);
                    259:        clb->sram.base = (sc->sc_memvme >> 16) & 0xff;
                    260:        DELAY(1000);
                    261:        clb->master.val = 0x01;         /* enable sram decoder */
                    262:        DELAY(1000);
                    263:
                    264:        printf(":");
                    265:        /*printf(" va=%x sc=%x slot 0x%02x vmes 0x%08x", sc->cl_reg, sc,
                    266:            sc->sc_memv, sc->sc_memvme);*/
                    267:
                    268:        while (sc->cl_reg->cl_gfrcr == 0x00)
                    269:                ;
                    270:        sc->cl_reg->cl_ccr = 0x10;      /* reset it */
                    271:        while (sc->cl_reg->cl_gfrcr == 0x00)
                    272:                ;
                    273:        if (sc->cl_reg->cl_gfrcr <= 0x10)
                    274:                printf(" rev %c", 'A' + sc->cl_reg->cl_gfrcr);
                    275:        else
                    276:                printf(" rev 0x%02x", sc->cl_reg->cl_gfrcr);
                    277:        printf("\n");
                    278:
                    279:        /* set up global registers */
                    280:        sc->cl_reg->cl_tpr = CL_TIMEOUT;
                    281:        sc->cl_reg->cl_rpilr = (ca->ca_ipl << 1) | 1;
                    282:        sc->cl_reg->cl_tpilr = (ca->ca_ipl << 1) | 1;
                    283:        sc->cl_reg->cl_mpilr = (ca->ca_ipl << 1) | 1;
                    284:
                    285:        sc->sc_memkv = vmemap(((struct vmessoftc *)parent)->sc_vme,
                    286:            sc->sc_memvme, WLRAMLEN, BUS_VMES);
                    287:        sc->sc_memp = (void *)kvtop(sc->sc_memkv);
                    288:        if (sc->sc_memkv == 0)
                    289:                printf("%s: got no memory", sc->sc_dev.dv_xname);
                    290:        else if (badvaddr(sc->sc_memkv, 1))
                    291:                printf("%s: cannot tap 0x%08x", sc->sc_dev.dv_xname, sc->sc_memkv);
                    292:        else {
                    293:                u_char *x = (u_char *)sc->sc_memkv;
                    294:
                    295:                /*printf("%s: pa 0x%08x va 0x%08x", sc->sc_dev.dv_xname,
                    296:                    sc->sc_memp, sc->sc_memkv);*/
                    297:                x[0] = 0xaa;
                    298:                x[1] = 0x55;
                    299:                if (x[0] != 0xaa || x[1] != 0x55)
                    300:                        printf(" 0x%02x 0x%02x", x[0], x[1]);
                    301:                x[0] = 0x55;
                    302:                x[1] = 0xaa;
                    303:                if (x[0] != 0x55 || x[1] != 0xaa)
                    304:                        printf(" 0x%02x 0x%02x", x[0], x[1]);
                    305:                bzero(x, WLRAMLEN);
                    306:        }
                    307:
                    308:        /* enable interrupts */
                    309:        sc->sc_ih_e.ih_fn = cl_intr;
                    310:        sc->sc_ih_e.ih_arg = sc;
                    311:        sc->sc_ih_e.ih_ipl = ca->ca_ipl;
                    312:        sc->sc_ih_e.ih_wantframe = 0;
                    313:
                    314:        sc->sc_ih_m.ih_fn = cl_intr;
                    315:        sc->sc_ih_m.ih_arg = sc;
                    316:        sc->sc_ih_m.ih_ipl = ca->ca_ipl;
                    317:        sc->sc_ih_m.ih_wantframe = 0;
                    318:
                    319:        sc->sc_ih_t.ih_fn = cl_intr;
                    320:        sc->sc_ih_t.ih_arg = sc;
                    321:        sc->sc_ih_t.ih_ipl = ca->ca_ipl;
                    322:        sc->sc_ih_t.ih_wantframe = 0;
                    323:
                    324:        sc->sc_ih_r.ih_fn = cl_intr;
                    325:        sc->sc_ih_r.ih_arg = sc;
                    326:        sc->sc_ih_r.ih_ipl = ca->ca_ipl;
                    327:        sc->sc_ih_r.ih_wantframe = 0;
                    328:
                    329:        snprintf(sc->sc_txintrname, sizeof sc->sc_txintrname,
                    330:            "%s_tx", self->dv_xname);
                    331:        snprintf(sc->sc_rxintrname, sizeof sc->sc_rxintrname,
                    332:            "%s_rx", self->dv_xname);
                    333:        snprintf(sc->sc_mxintrname, sizeof sc->sc_mxintrname,
                    334:            "%s_mx", self->dv_xname);
                    335:
                    336:        vmeintr_establish(ca->ca_vec + 0, &sc->sc_ih_e, sc->sc_rxintrname);
                    337:        vmeintr_establish(ca->ca_vec + 1, &sc->sc_ih_m, sc->sc_mxintrname);
                    338:        vmeintr_establish(ca->ca_vec + 2, &sc->sc_ih_t, sc->sc_txintrname);
                    339:        vmeintr_establish(ca->ca_vec + 3, &sc->sc_ih_r, sc->sc_rxintrname);
                    340:
                    341:        p = (void *)sc->sc_memkv;
                    342:        s = splhigh();
                    343:        for (i = 0; i < CLCD_PORTS_PER_CHIP; i++) {
                    344:                for (j = 0; j < 2; j++) {
                    345:                        sc->sc_cl[i].rx[j] = p;
                    346:                        sc->sc_cl[i].rxp[j] = (void *)(p - (void *)sc->sc_memkv);
                    347:                        /*printf("%d:%d rx v %x p %x\n",
                    348:                            i, j, sc->sc_cl[i].rx[j], sc->sc_cl[i].rxp[j]);*/
                    349:                        p += CL_BUFSIZE;
                    350:                }
                    351:                for (j = 0; j < 2; j++) {
                    352:                        sc->sc_cl[i].tx[j] = p;
                    353:                        sc->sc_cl[i].txp[j] = (void *)(p - (void *)sc->sc_memkv);
                    354:                        /*printf("%d:%d tx v %x p %x\n",
                    355:                            i, j, sc->sc_cl[i].tx[j], sc->sc_cl[i].txp[j]);*/
                    356:                        p += CL_BUFSIZE;
                    357:                }
                    358:                cl_initchannel(sc, i);
                    359:        }
                    360:        splx(s);
                    361: }
                    362:
                    363: static void
                    364: cl_initchannel(sc, channel)
                    365:        struct wlsoftc *sc;
                    366:        int channel;
                    367: {
                    368:        struct clreg *cl_reg = sc->cl_reg;
                    369:
                    370:        /* set up option registers */
                    371:        cl_reg->cl_car  = channel;
                    372:        cl_reg->cl_livr = sc->sc_vec;
                    373:        cl_reg->cl_ier  = 0x00;
                    374:        cl_reg->cl_cmr  = 0x02;
                    375:        cl_reg->cl_cor1 = 0x17;
                    376:        cl_reg->cl_cor2 = 0x00;
                    377:        cl_reg->cl_cor3 = 0x02;
                    378:        cl_reg->cl_cor4 = 0xec;
                    379:        cl_reg->cl_cor5 = 0xec;
                    380:        cl_reg->cl_cor6 = 0x00;
                    381:        cl_reg->cl_cor7 = 0x00;
                    382:        cl_reg->cl_schr1 = 0x00;
                    383:        cl_reg->cl_schr2 = 0x00;
                    384:        cl_reg->cl_schr3 = 0x00;
                    385:        cl_reg->cl_schr4 = 0x00;
                    386:        cl_reg->cl_scrl = 0x00;
                    387:        cl_reg->cl_scrh = 0x00;
                    388:        cl_reg->cl_lnxt = 0x00;
                    389:        cl_reg->cl_rbpr = 0x40; /* 9600 */
                    390:        cl_reg->cl_rcor = 0x01;
                    391:        cl_reg->cl_tbpr = 0x40; /* 9600 */
                    392:        cl_reg->cl_tcor = 0x01 << 5;
                    393:        /* console port should be 0x88 already */
                    394:        cl_reg->cl_msvr_rts     = 0x00;
                    395:        cl_reg->cl_msvr_dtr     = 0x00;
                    396:        cl_reg->cl_rtprl        = CL_RX_TIMEOUT;
                    397:        cl_reg->cl_rtprh        = 0x00;
                    398:        sc->cl_reg->cl_ccr = 0x20;
                    399:        while (sc->cl_reg->cl_ccr != 0)
                    400:                ;
                    401: }
                    402:
                    403:
                    404: int cldefaultrate = TTYDEF_SPEED;
                    405:
                    406: int clmctl (dev, bits, how)
                    407:        dev_t dev;
                    408:        int bits;
                    409:        int how;
                    410: {
                    411:        int s;
                    412:        struct wlsoftc *sc;
                    413:        /* should only be called with valid device */
                    414:        sc = (struct wlsoftc *) wl_cd.cd_devs[CL_UNIT(dev)];
                    415:        /*
                    416:        printf("mctl: dev %x, bits %x, how %x,\n",dev, bits, how);
                    417:        */
                    418:        /* settings are currently ignored */
                    419:        s = splcl();
                    420:        switch (how) {
                    421:        case DMSET:
                    422:                if( bits & TIOCM_RTS) {
                    423:                        sc->cl_reg->cl_msvr_rts = 0x01;
                    424:                } else {
                    425:                        sc->cl_reg->cl_msvr_rts = 0x00;
                    426:                }
                    427:                if( bits & TIOCM_DTR) {
                    428:                        sc->cl_reg->cl_msvr_dtr = 0x02;
                    429:                } else {
                    430:                        sc->cl_reg->cl_msvr_dtr = 0x00;
                    431:                }
                    432:                break;
                    433:
                    434:        case DMBIC:
                    435:                if( bits & TIOCM_RTS) {
                    436:                        sc->cl_reg->cl_msvr_rts = 0x00;
                    437:                }
                    438:                if( bits & TIOCM_DTR) {
                    439:                        sc->cl_reg->cl_msvr_dtr = 0x00;
                    440:                }
                    441:                break;
                    442:
                    443:        case DMBIS:
                    444:                if( bits & TIOCM_RTS) {
                    445:                        sc->cl_reg->cl_msvr_rts = 0x01;
                    446:                }
                    447:                if( bits & TIOCM_DTR) {
                    448:                        sc->cl_reg->cl_msvr_dtr = 0x02;
                    449:                }
                    450:                break;
                    451:
                    452:        case DMGET:
                    453:                bits = 0;
                    454:
                    455:                {
                    456:                        u_char msvr;
                    457:                        msvr = sc->cl_reg->cl_msvr_rts;
                    458:                        if( msvr & 0x80) {
                    459:                                bits |= TIOCM_DSR;
                    460:                        }
                    461:                        if( msvr & 0x40) {
                    462:                                bits |= TIOCM_CD;
                    463:                        }
                    464:                        if( msvr & 0x20) {
                    465:                                bits |= TIOCM_CTS;
                    466:                        }
                    467:                        if( msvr & 0x10) {
                    468:                                bits |= TIOCM_DTR;
                    469:                        }
                    470:                        if( msvr & 0x02) {
                    471:                                bits |= TIOCM_DTR;
                    472:                        }
                    473:                        if( msvr & 0x01) {
                    474:                                bits |= TIOCM_RTS;
                    475:                        }
                    476:
                    477:                }
                    478:                break;
                    479:        }
                    480:        splx(s);
                    481: #if 0
                    482:        bits = 0;
                    483:        /* proper defaults? */
                    484:        bits |= TIOCM_DTR;
                    485:        bits |= TIOCM_RTS;
                    486:        bits |= TIOCM_CTS;
                    487:        bits |= TIOCM_CD;
                    488:        /*      bits |= TIOCM_RI; */
                    489:        bits |= TIOCM_DSR;
                    490: #endif
                    491:
                    492:        /*
                    493:        printf("retbits %x\n", bits);
                    494:        */
                    495:        return(bits);
                    496: }
                    497:
                    498: int
                    499: wlopen(dev, flag, mode, p)
                    500:        dev_t dev;
                    501:        int flag;
                    502:        int mode;
                    503:        struct proc *p;
                    504: {
                    505:        int s, unit, channel;
                    506:        struct cl_info *cl;
                    507:        struct wlsoftc *sc;
                    508:        struct tty *tp;
                    509:
                    510:        unit = CL_UNIT(dev);
                    511:        if (unit >= wl_cd.cd_ndevs ||
                    512:                (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL) {
                    513:                return (ENODEV);
                    514:        }
                    515:        channel = CL_CHANNEL(dev);
                    516:        cl = &sc->sc_cl[channel];
                    517:        s = splcl();
                    518:        if (cl->tty) {
                    519:                tp = cl->tty;
                    520:        } else {
                    521:                tp = cl->tty = ttymalloc();
                    522:        }
                    523:        tp->t_oproc = clstart;
                    524:        tp->t_param = clparam;
                    525:        tp->t_dev = dev;
                    526:
                    527:        if ((tp->t_state & TS_ISOPEN) == 0) {
                    528:                tp->t_state |= TS_WOPEN;
                    529:                ttychars(tp);
                    530:                if (tp->t_ispeed == 0) {
                    531:                        /*
                    532:                         * only when cleared do we reset to defaults.
                    533:                         */
                    534:                        tp->t_iflag = TTYDEF_IFLAG;
                    535:                        tp->t_oflag = TTYDEF_OFLAG;
                    536:                        tp->t_lflag = TTYDEF_LFLAG;
                    537:                        tp->t_ispeed = tp->t_ospeed = cldefaultrate;
                    538:
                    539:                        tp->t_cflag = TTYDEF_CFLAG;
                    540:                }
                    541:                /*
                    542:                 * do these all the time
                    543:                 */
                    544:                if (cl->cl_swflags & TIOCFLAG_CLOCAL)
                    545:                        tp->t_cflag |= CLOCAL;
                    546:                if (cl->cl_swflags & TIOCFLAG_CRTSCTS)
                    547:                        tp->t_cflag |= CRTSCTS;
                    548:                if (cl->cl_swflags & TIOCFLAG_MDMBUF)
                    549:                        tp->t_cflag |= MDMBUF;
                    550:                clparam(tp, &tp->t_termios);
                    551:                ttsetwater(tp);
                    552:
                    553:                (void)clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
                    554:                tp->t_state |= TS_CARR_ON;
                    555:                {
                    556:                        u_char save = sc->cl_reg->cl_car;
                    557:                        sc->cl_reg->cl_car = channel;
                    558:                        sc->cl_reg->cl_ier = IER_MDM | IER_RXD;
                    559:                        sc->cl_reg->cl_car = save;
                    560:                }
                    561:        } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
                    562:                splx(s);
                    563:                return(EBUSY);
                    564:        }
                    565:
                    566:        splx(s);
                    567:        /*
                    568:         * Reset the tty pointer, as there could have been a dialout
                    569:         * use of the tty with a dialin open waiting.
                    570:         */
                    571:        tp->t_dev = dev;
                    572:        return((*linesw[tp->t_line].l_open)(dev, tp));
                    573: }
                    574:
                    575: int clparam(tp, t)
                    576:        struct tty *tp;
                    577:        struct termios *t;
                    578: {
                    579:        int unit, channel;
                    580:        struct wlsoftc *sc;
                    581:        int s;
                    582:        dev_t dev;
                    583:
                    584:        dev = tp->t_dev;
                    585:        unit = CL_UNIT(dev);
                    586:        if (unit >= wl_cd.cd_ndevs ||
                    587:                (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL) {
                    588:                return (ENODEV);
                    589:        }
                    590:        channel = CL_CHANNEL(dev);
                    591:        tp->t_ispeed = t->c_ispeed;
                    592:        tp->t_ospeed = t->c_ospeed;
                    593:        tp->t_cflag = t->c_cflag;
                    594:        clccparam(sc, t, channel);
                    595:        s = splcl();
                    596:        cl_unblock(tp);
                    597:        splx(s);
                    598:        return 0;
                    599: }
                    600:
                    601: void cloutput(tp)
                    602:        struct tty *tp;
                    603: {
                    604:        int cc, s, unit, cnt;
                    605:        u_char *tptr;
                    606:        int channel;
                    607:        struct wlsoftc *sc;
                    608:        dev_t dev;
                    609:        u_char cl_obuffer[CLCDBUF+1];
                    610:
                    611:        dev = tp->t_dev;
                    612:        unit = CL_UNIT(dev);
                    613:        if (unit >= wl_cd.cd_ndevs ||
                    614:                (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL) {
                    615:                return;
                    616:        }
                    617:        channel = CL_CHANNEL(dev);
                    618:
                    619:        if ((tp->t_state & TS_ISOPEN) == 0)
                    620:                return;
                    621:
                    622:        s = splcl();
                    623:        cc = tp->t_outq.c_cc;
                    624:        while (cc > 0) {
                    625: /*XXX*/
                    626:                cnt = min(CLCDBUF,cc);
                    627:                cnt = q_to_b(&tp->t_outq, cl_obuffer, cnt);
                    628:                if (cnt == 0) {
                    629:                        break;
                    630:                }
                    631:                for (tptr = cl_obuffer; tptr < &cl_obuffer[cnt]; tptr++) {
                    632:                        clputc(sc, channel, *tptr);
                    633:                }
                    634:                cc -= cnt;
                    635:        }
                    636:        splx(s);
                    637: }
                    638:
                    639: int
                    640: wlclose(dev, flag, mode, p)
                    641:        dev_t dev;
                    642:        int flag;
                    643:        int mode;
                    644:        struct proc *p;
                    645: {
                    646:        int unit, channel;
                    647:        struct tty *tp;
                    648:        struct cl_info *cl;
                    649:        struct wlsoftc *sc;
                    650:        int s;
                    651:        unit = CL_UNIT(dev);
                    652:        if (unit >= wl_cd.cd_ndevs ||
                    653:                (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL) {
                    654:                return (ENODEV);
                    655:        }
                    656:        channel = CL_CHANNEL(dev);
                    657:        cl = &sc->sc_cl[channel];
                    658:        tp = cl->tty;
                    659:        (*linesw[tp->t_line].l_close)(tp, flag);
                    660:
                    661:        s = splcl();
                    662:
                    663:        sc->cl_reg->cl_car = channel;
                    664:        if((tp->t_cflag & HUPCL) != 0) {
                    665:                sc->cl_reg->cl_msvr_rts = 0x00;
                    666:                sc->cl_reg->cl_msvr_dtr = 0x00;
                    667:                sc->cl_reg->cl_ccr = 0x05;
                    668:                sc->cl_reg->cl_ier = 0x00;
                    669:        }
                    670:
                    671:        splx(s);
                    672:        ttyclose(tp);
                    673:
                    674: #if 0
                    675:        cl->tty = NULL;
                    676: #endif
                    677:        return (0);
                    678: }
                    679:
                    680: int
                    681: wlread(dev, uio, flag)
                    682:        dev_t dev;
                    683:        struct uio *uio;
                    684:        int flag;
                    685: {
                    686:        int unit, channel;
                    687:        struct tty *tp;
                    688:        struct cl_info *cl;
                    689:        struct wlsoftc *sc;
                    690:        unit = CL_UNIT(dev);
                    691:        if (unit >= wl_cd.cd_ndevs ||
                    692:                (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL) {
                    693:                return (ENODEV);
                    694:        }
                    695:        channel = CL_CHANNEL(dev);
                    696:        cl = &sc->sc_cl[channel];
                    697:        tp = cl->tty;
                    698:        if (!tp)
                    699:                return ENXIO;
                    700:        return((*linesw[tp->t_line].l_read)(tp, uio, flag));
                    701: }
                    702: int
                    703: wlwrite(dev, uio, flag)
                    704:        dev_t dev;
                    705:        struct uio *uio;
                    706:        int flag;
                    707: {
                    708:        int unit, channel;
                    709:        struct tty *tp;
                    710:        struct cl_info *cl;
                    711:        struct wlsoftc *sc;
                    712:        unit = CL_UNIT(dev);
                    713:        if (unit >= wl_cd.cd_ndevs ||
                    714:                (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL) {
                    715:                return (ENODEV);
                    716:        }
                    717:        channel = CL_CHANNEL(dev);
                    718:        cl = &sc->sc_cl[channel];
                    719:        tp = cl->tty;
                    720:        if (!tp)
                    721:                return ENXIO;
                    722:        return((*linesw[tp->t_line].l_write)(tp, uio, flag));
                    723: }
                    724: int
                    725: wlioctl(dev, cmd, data, flag, p)
                    726:        dev_t dev;
                    727:        u_long cmd;
                    728:        caddr_t data;
                    729:        int flag;
                    730:        struct proc *p;
                    731: {
                    732:        int error;
                    733:        int unit, channel;
                    734:        struct tty *tp;
                    735:        struct cl_info *cl;
                    736:        struct wlsoftc *sc;
                    737:        unit = CL_UNIT(dev);
                    738:        if (unit >= wl_cd.cd_ndevs ||
                    739:                (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL) {
                    740:                return (ENODEV);
                    741:        }
                    742:        channel = CL_CHANNEL(dev);
                    743:        cl = &sc->sc_cl[channel];
                    744:        tp = cl->tty;
                    745:        if (!tp)
                    746:                return ENXIO;
                    747:
                    748:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
                    749:        if (error >= 0)
                    750:                return(error);
                    751:
                    752:        error = ttioctl(tp, cmd, data, flag, p);
                    753:        if (error >= 0)
                    754:                return(error);
                    755:
                    756:        switch (cmd) {
                    757:        case TIOCSBRK:
                    758:                /* */
                    759:                break;
                    760:
                    761:        case TIOCCBRK:
                    762:                /* */
                    763:                break;
                    764:
                    765:        case TIOCSDTR:
                    766:                (void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
                    767:                break;
                    768:
                    769:        case TIOCCDTR:
                    770:                (void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
                    771:                break;
                    772:
                    773:        case TIOCMSET:
                    774:                (void) clmctl(dev, *(int *) data, DMSET);
                    775:                break;
                    776:
                    777:        case TIOCMBIS:
                    778:                (void) clmctl(dev, *(int *) data, DMBIS);
                    779:                break;
                    780:
                    781:        case TIOCMBIC:
                    782:                (void) clmctl(dev, *(int *) data, DMBIC);
                    783:                break;
                    784:
                    785:        case TIOCMGET:
                    786:                *(int *)data = clmctl(dev, 0, DMGET);
                    787:                break;
                    788:        case TIOCGFLAGS:
                    789:                *(int *)data = cl->cl_swflags;
                    790:                break;
                    791:        case TIOCSFLAGS:
                    792:                error = suser(p, 0);
                    793:                if (error != 0)
                    794:                        return(EPERM);
                    795:
                    796:                cl->cl_swflags = *(int *)data;
                    797:                cl->cl_swflags &= /* only allow valid flags */
                    798:                        (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
                    799:                break;
                    800:        default:
                    801:                return(ENOTTY);
                    802:        }
                    803:
                    804:        return 0;
                    805: }
                    806: int
                    807: wlstop(tp, flag)
                    808:        struct tty *tp;
                    809:        int flag;
                    810: {
                    811:        int s;
                    812:
                    813:        s = splcl();
                    814:        if (tp->t_state & TS_BUSY) {
                    815:                if ((tp->t_state & TS_TTSTOP) == 0)
                    816:                        tp->t_state |= TS_FLUSH;
                    817:        }
                    818:        splx(s);
                    819:        return 0;
                    820: }
                    821:
                    822: static u_char
                    823: clgetc(sc, channel)
                    824:        struct wlsoftc *sc;
                    825:        int *channel;
                    826: {
                    827:        struct clreg *cl_reg;
                    828:        u_char reoir, licr, isrl, fifo_cnt, data;
                    829:
                    830:        cl_reg = sc->cl_reg;
                    831:        /* if no receive interrupt pending wait */
                    832:        if ((cl_reg->cl_rir & RIR_REN) == 0) {
                    833:                return 0;
                    834:        }
                    835:        /* XXX do we need to suck the entire FIFO contents? */
                    836:        licr = cl_reg->cl_licr;
                    837:        *channel = (licr >> 2) & 0x3;
                    838:        /* is the interrupt for us (port 0) */
                    839:        /* the character is for us yea. */
                    840:        isrl = cl_reg->cl_risrl;
                    841: #if 0
                    842:        if (isrl & 0x01) {
                    843:                status = BREAK;
                    844:        }
                    845:        if (isrl & 0x02) {
                    846:                status = FRAME;
                    847:        }
                    848:        if (isrl & 0x04) {
                    849:                status = PARITY;
                    850:        }
                    851:        if (isrl & 0x08) {
                    852:                status = OVERFLOW;
                    853:        }
                    854:        /* we do not have special characters ;-) */
                    855: #endif
                    856:        fifo_cnt = cl_reg->cl_rfoc;
                    857:        if (fifo_cnt > 0) {
                    858:                data = cl_reg->cl_rdr;
                    859:                cl_reg->cl_teoir = 0x00;
                    860:        } else {
                    861:                data = 0;
                    862:                cl_reg->cl_teoir = 0x08;
                    863:        }
                    864:        return data;
                    865: }
                    866:
                    867: int
                    868: clccparam(sc, par, channel)
                    869:        struct wlsoftc *sc;
                    870:        struct termios *par;
                    871:        int channel;
                    872: {
                    873:        u_int divisor, clk, clen;
                    874:        int s, imask, ints;
                    875:
                    876:        s = splcl();
                    877:        sc->cl_reg->cl_car = channel;
                    878:        if (par->c_ospeed == 0) {
                    879:                /* disconnect, drop RTS DTR stop receiver */
                    880:                sc->cl_reg->cl_msvr_rts = 0x00;
                    881:                sc->cl_reg->cl_msvr_dtr = 0x00;
                    882:                sc->cl_reg->cl_ccr = 0x05;
                    883:                splx(s);
                    884:                return (0xff);
                    885:        }
                    886:
                    887:        sc->cl_reg->cl_msvr_rts = 0x03;
                    888:        sc->cl_reg->cl_msvr_dtr = 0x03;
                    889:
                    890:        divisor = cl_clkdiv(par->c_ospeed);
                    891:        clk     = cl_clknum(par->c_ospeed);
                    892:        sc->cl_reg->cl_tbpr = divisor;
                    893:        sc->cl_reg->cl_tcor = clk << 5;
                    894:        divisor = cl_clkdiv(par->c_ispeed);
                    895:        clk     = cl_clknum(par->c_ispeed);
                    896:        sc->cl_reg->cl_rbpr = divisor;
                    897:        sc->cl_reg->cl_rcor = clk;
                    898:        sc->cl_reg->cl_rtprl = cl_clkrxtimeout(par->c_ispeed);
                    899:        sc->cl_reg->cl_rtprh = 0x00;
                    900:
                    901:        switch (par->c_cflag & CSIZE) {
                    902:        case CS5:
                    903:                clen = 4; /* this is the mask for the chip. */
                    904:                imask = 0x1F;
                    905:                break;
                    906:        case CS6:
                    907:                clen = 5;
                    908:                imask = 0x3F;
                    909:                break;
                    910:        case CS7:
                    911:                clen = 6;
                    912:                imask = 0x7F;
                    913:                break;
                    914:        default:
                    915:                clen = 7;
                    916:                imask = 0xFF;
                    917:        }
                    918:        sc->cl_reg->cl_cor3 = par->c_cflag & PARENB ? 4 : 2;
                    919:
                    920:        {
                    921:                u_char cor1;
                    922:                if (par->c_cflag & PARENB) {
                    923:                        if (par->c_cflag & PARODD) {
                    924:                                cor1 = 0xE0 | clen ; /* odd */
                    925:                        } else {
                    926:                                cor1 = 0x40 | clen ; /* even */
                    927:                        }
                    928:                } else {
                    929:                        cor1 = 0x10 | clen; /* ignore parity */
                    930:                }
                    931:                if (sc->cl_reg->cl_cor1 != cor1) {
                    932:                        sc->cl_reg->cl_cor1 = cor1;
                    933:                        sc->cl_reg->cl_ccr = 0x20;
                    934:                        while (sc->cl_reg->cl_ccr != 0)
                    935:                                ;
                    936:                }
                    937:        }
                    938:
                    939:        if ((par->c_cflag & CREAD) == 0) {
                    940:                sc->cl_reg->cl_ccr = 0x08;
                    941:        } else {
                    942:                sc->cl_reg->cl_ccr = 0x0a;
                    943:        }
                    944:        while (sc->cl_reg->cl_ccr != 0)
                    945:                ;
                    946:
                    947:        ints = 0;
                    948: #define SCC_DSR 0x80
                    949: #define SCC_DCD 0x40
                    950: #define SCC_CTS 0x20
                    951:        if ((par->c_cflag & CLOCAL) == 0) {
                    952:                ints |= SCC_DCD;
                    953:        }
                    954:        if ((par->c_cflag & CCTS_OFLOW) != 0) {
                    955:                ints |= SCC_CTS;
                    956:        }
                    957:        if ((par->c_cflag & CRTSCTS) != 0) {
                    958:                ints |= SCC_CTS;
                    959:        }
                    960: #ifdef DONT_LET_HARDWARE
                    961:        if ((par->c_cflag & CCTS_IFLOW) != 0) {
                    962:                ints |= SCC_DSR;
                    963:        }
                    964: #endif
                    965:        sc->cl_reg->cl_cor4 = ints | CL_FIFO_CNT;
                    966:        sc->cl_reg->cl_cor5 = ints | CL_FIFO_CNT;
                    967:
                    968:        return imask;
                    969: }
                    970:
                    971: static int clknum = 0;
                    972:
                    973: u_char
                    974: cl_clkdiv(speed)
                    975:        int speed;
                    976: {
                    977:        int i = 0;
                    978:
                    979:        if (cl_clocks[clknum].speed == speed)
                    980:                return cl_clocks[clknum].divisor;
                    981:
                    982:        for  (i = 0; cl_clocks[i].speed != 0; i++) {
                    983:                if (cl_clocks[i].speed == speed) {
                    984:                        clknum = i;
                    985:                        return cl_clocks[clknum].divisor;
                    986:                }
                    987:        }
                    988:
                    989:        /* return some sane value if unknown speed */
                    990:        clknum = 4;
                    991:        return cl_clocks[clknum].divisor;
                    992: }
                    993: u_char
                    994: cl_clknum(speed)
                    995:        int speed;
                    996: {
                    997:        int found = 0;
                    998:        int i = 0;
                    999:        if (cl_clocks[clknum].speed == speed) {
                   1000:                return cl_clocks[clknum].clock;
                   1001:        }
                   1002:        for  (i = 0; found != 0 && cl_clocks[i].speed != 0; i++) {
                   1003:                if (cl_clocks[clknum].speed == speed) {
                   1004:                        clknum = i;
                   1005:                        return cl_clocks[clknum].clock;
                   1006:                }
                   1007:        }
                   1008:        /* return some sane value if unknown speed */
                   1009:        return cl_clocks[4].clock;
                   1010: }
                   1011: u_char
                   1012: cl_clkrxtimeout(speed)
                   1013:        int speed;
                   1014: {
                   1015:        int i = 0;
                   1016:        if (cl_clocks[clknum].speed == speed) {
                   1017:                return cl_clocks[clknum].rx_timeout;
                   1018:        }
                   1019:        for  (i = 0; cl_clocks[i].speed != 0; i++) {
                   1020:                if (cl_clocks[i].speed == speed) {
                   1021:                        clknum = i;
                   1022:                        return cl_clocks[clknum].rx_timeout;
                   1023:                }
                   1024:        }
                   1025:        /* return some sane value if unknown speed */
                   1026:        return cl_clocks[4].rx_timeout;
                   1027: }
                   1028: void
                   1029: cl_unblock(tp)
                   1030:        struct tty *tp;
                   1031: {
                   1032:        tp->t_state &= ~TS_FLUSH;
                   1033:        if (tp->t_outq.c_cc != 0)
                   1034:                clstart(tp);
                   1035: }
                   1036: void
                   1037: clstart(tp)
                   1038:        struct tty *tp;
                   1039: {
                   1040:        dev_t dev;
                   1041:        u_char cbuf;
                   1042:        struct wlsoftc *sc;
                   1043:        int channel, unit, s, cnt;
                   1044:
                   1045:        dev = tp->t_dev;
                   1046:        channel = CL_CHANNEL(dev);
                   1047:        unit = CL_UNIT(dev);
                   1048:        if (unit >= wl_cd.cd_ndevs ||
                   1049:            (sc = (struct wlsoftc *) wl_cd.cd_devs[unit]) == NULL) {
                   1050:                return;
                   1051:        }
                   1052:
                   1053:        if ((tp->t_state & TS_ISOPEN) == 0)
                   1054:                return;
                   1055:
                   1056:        s = splcl();
                   1057:        if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP | TS_FLUSH)) == 0) {
                   1058:                tp->t_state |= TS_BUSY;
                   1059:                sc->cl_reg->cl_car = channel;
                   1060:                sc->cl_reg->cl_ier = sc->cl_reg->cl_ier | IER_TXMPTY | IER_TXD;
                   1061: #if 0
                   1062:                zscnputc(0, 'S');
                   1063: #endif
                   1064:        }
                   1065:        splx(s);
                   1066: }
                   1067:
                   1068: int
                   1069: cl_intr(sc, vec)
                   1070:        struct wlsoftc *sc;
                   1071:        int vec;
                   1072: {
                   1073:        u_char livr = sc->cl_reg->cl_livr;
                   1074:        u_char stk = sc->cl_reg->cl_stk;
                   1075:        int i = 0;
                   1076:
                   1077:        stk = ((stk & 0x80) >> 6) | (stk & 0x01);
                   1078: #if 1
                   1079:        zscnputc(0, '[');
                   1080:        zscnputc(0, '0' + vec - 0x70);
                   1081:        zscnputc(0, '0' + livr - 0x70);
                   1082:        zscnputc(0, '0' + stk);
                   1083:        zscnputc(0, ']');
                   1084: #endif
                   1085:
                   1086:        switch (stk & 3) {
                   1087:        case 0:
                   1088: #if 0
                   1089:                i += cl_rxintr(sc);
                   1090:                i += cl_mintr(sc);
                   1091:                i += cl_txintr(sc);
                   1092: #else
                   1093:                i += cl_rxintr(sc);
                   1094: #endif
                   1095:                break;
                   1096:        case 1:
                   1097:                i += cl_mintr(sc);
                   1098:                break;
                   1099:        case 2:
                   1100:                i += cl_txintr(sc);
                   1101:                break;
                   1102:        case 3:
                   1103:                i += cl_rxintr(sc);
                   1104:                break;
                   1105:        }
                   1106:        return (i);
                   1107: }
                   1108:
                   1109: int
                   1110: cl_mintr(sc)
                   1111:        struct wlsoftc *sc;
                   1112: {
                   1113:        u_char mir, misr, msvr;
                   1114:        int channel;
                   1115:        struct tty *tp;
                   1116:
                   1117:        mir = sc->cl_reg->cl_mir;
                   1118:        if((mir & MIR_MACT) == 0)
                   1119:                return 0;
                   1120:        zscnputc(0, 'M');
                   1121:
                   1122:        misr = sc->cl_reg->cl_misr;
                   1123:        msvr = sc->cl_reg->cl_msvr_rts;
                   1124:        channel = mir & MIR_MCM_M;
                   1125:
                   1126:        printf("stk 0x%x mir 0x%x chan 0x%x\n",
                   1127:            sc->cl_reg->cl_stk, mir, channel);
                   1128:
                   1129:        if (misr & MISR_TIMER1) {
                   1130:                /* timers are not currently used?? */
                   1131:                log(LOG_WARNING, "cl_mintr: channel %x timer 1 unexpected\n",channel);
                   1132:        }
                   1133:        if (misr & MISR_TIMER2) {
                   1134:                /* timers are not currently used?? */
                   1135:                log(LOG_WARNING, "cl_mintr: channel %x timer 2 unexpected\n",channel);
                   1136:        }
                   1137:        if (misr & MISR_CTSCHG) {
                   1138:                log(LOG_WARNING, "cl_mintr: channel %x cts %x\n",channel,
                   1139:                    ((msvr & 0x20) != 0x0));
                   1140:        }
                   1141:        if (misr & MISR_CDCHG) {
                   1142:                struct tty *tp = sc->sc_cl[channel].tty;
                   1143:                log(LOG_WARNING, "cl_mintr: channel %x cd %x\n",channel,
                   1144:                    ((msvr & 0x40) != 0x0));
                   1145:                ttymodem(tp, ((msvr & 0x40) != 0x0) );
                   1146:        }
                   1147:        if (misr & MISR_DSRCHG) {
                   1148:                log(LOG_WARNING, "cl_mintr: channel %x dsr %x\n",channel,
                   1149:                    ((msvr & 0x80) != 0x0));
                   1150:        }
                   1151:        sc->cl_reg->cl_meoir = 0x00;
                   1152:        return 1;
                   1153: }
                   1154:
                   1155: int
                   1156: cl_txintr(sc)
                   1157:        struct wlsoftc *sc;
                   1158: {
                   1159:        static int empty = 0;
                   1160:        u_char tir, cmr, teoir, tisr, tftc;
                   1161:        int chan;
                   1162:        struct tty *tp;
                   1163:        int cnt;
                   1164:        u_char buffer[CL_FIFO_MAX +1];
                   1165:        u_char *tptr;
                   1166:        u_char dmabsts;
                   1167:        int nbuf, busy, resid;
                   1168:        void *pbuffer;
                   1169:
                   1170:        tir = sc->cl_reg->cl_tir;
                   1171:        if((tir & (TIR_TEN|TIR_TACT)) == 0)
                   1172:                return 0;
                   1173: #if 0
                   1174:        zscnputc(0, 'T');
                   1175: #endif
                   1176:
                   1177:        cmr = sc->cl_reg->cl_cmr;
                   1178:        chan = tir & TIR_TCN_M;
                   1179:        tisr = sc->cl_reg->cl_tisr;
                   1180:        tftc = sc->cl_reg->cl_tftc;
                   1181:
                   1182:        printf("stk 0x%x tir 0x%x chan 0x%x cmr 0x%x tisr 0x%x tftc 0x%x\n",
                   1183:            sc->cl_reg->cl_stk, tir, chan, cmr, tisr, tftc);
                   1184:
                   1185:        sc->sc_cl[chan].txcnt++;
                   1186:        tp = sc->sc_cl[chan].tty;
                   1187:
                   1188:        if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) {
                   1189:                sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~(IER_TXMPTY|IER_TXD);
                   1190:                sc->cl_reg->cl_teoir = TEOIR_NOTRANSF;
                   1191:                return 1;
                   1192:        }
                   1193:
                   1194:        switch (cmr & CL_TXMASK) {
                   1195:        case CL_TXINTR:
                   1196:                cnt = min((int)tftc, tp->t_outq.c_cc);
                   1197:                if (cnt != 0) {
                   1198:                        /*printf("s%d ", cnt);*/
                   1199:                        cnt = q_to_b(&tp->t_outq, buffer, cnt);
                   1200:                        /*printf("%d:", cnt);*/
                   1201:                        empty = 0;
                   1202:                        for (tptr = buffer; tptr < &buffer[cnt]; tptr++) {
                   1203:                                /*printf("%c", *tptr);*/
                   1204:                                sc->cl_reg->cl_tdr = *tptr;
                   1205:                        }
                   1206:                        /*printf("\n", cnt);*/
                   1207:                        teoir = 0;
                   1208:                } else {
                   1209:                        if (empty > 5 && ((empty % 20000 )== 0))
                   1210:                                log(LOG_WARNING, "cl_txintr empty intr %d chan %d\n",
                   1211:                                    empty, chan);
                   1212:                        empty++;
                   1213:                        teoir = TEOIR_NOTRANSF;
                   1214:                        if (tp->t_state & TS_BUSY) {
                   1215:                                tp->t_state &= ~(TS_BUSY | TS_FLUSH);
                   1216:                                if (tp->t_state & TS_ASLEEP) {
                   1217:                                        tp->t_state &= ~TS_ASLEEP;
                   1218:                                        wakeup((caddr_t) &tp->t_outq);
                   1219:                                }
                   1220:                                selwakeup(&tp->t_wsel);
                   1221:                        }
                   1222:                        sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~(IER_TXMPTY|IER_TXD);
                   1223:                }
                   1224:                break;
                   1225:        default:
                   1226:                log(LOG_WARNING, "cl_txintr unknown mode %x\n", cmr);
                   1227:                /* we probably will go to hell quickly now */
                   1228:                teoir = TEOIR_NOTRANSF;
                   1229:                break;
                   1230:        }
                   1231:        sc->cl_reg->cl_teoir = teoir;
                   1232:        return (1);
                   1233: }
                   1234:
                   1235: int
                   1236: cl_rxintr(sc)
                   1237:        struct wlsoftc *sc;
                   1238: {
                   1239:        u_char rir, chan, cmr, risrl;
                   1240:        u_char buffer[CL_FIFO_MAX +1];
                   1241:        u_char reoir = REOIR_NOTRANSF, fifocnt, c;
                   1242:        struct tty *tp;
                   1243:        int i;
                   1244:
                   1245:        rir = sc->cl_reg->cl_rir;
                   1246:        if((rir & RIR_RACT) == 0)
                   1247:                return 0;
                   1248: #if 0
                   1249:        zscnputc(0, 'R');
                   1250: #endif
                   1251:
                   1252:        cmr = sc->cl_reg->cl_cmr;
                   1253:        risrl = sc->cl_reg->cl_risrl;
                   1254:        chan = rir & RIR_RCN_M;
                   1255:
                   1256:        /*printf("stk 0x%x rir 0x%x chan 0x%x cmr 0x%x risrl 0x%x\n",
                   1257:            sc->cl_reg->cl_stk, rir, chan, cmr, risrl);*/
                   1258:
                   1259:        sc->sc_cl[chan].rxcnt++;
                   1260:
                   1261:        if (risrl & RISRL_TIMEOUT) {
                   1262:                reoir = REOIR_NOTRANSF;
                   1263:        } else if (risrl & RISRL_OE) {
                   1264:                cl_overflow(sc, chan, &sc->sc_fotime, "fifo");
                   1265:                reoir = REOIR_NOTRANSF;
                   1266:        } else if (risrl & RISRL_PE) {
                   1267:                cl_parity(sc, chan);
                   1268:                reoir = REOIR_NOTRANSF;
                   1269:        } else if (risrl & RISRL_FE) {
                   1270:                cl_frame(sc, chan);
                   1271:                reoir = REOIR_NOTRANSF;
                   1272:        } else if (risrl & RISRL_BREAK) {
                   1273:                cl_break(sc, chan);
                   1274:                reoir = REOIR_NOTRANSF;
                   1275:        } else {
                   1276:                switch (cmr & CL_RXMASK) {
                   1277:                case CL_RXINTR:
                   1278:                        fifocnt = sc->cl_reg->cl_rfoc;
                   1279:                        tp = sc->sc_cl[chan].tty;
                   1280:                        for (i = 0; i < fifocnt; i++)
                   1281:                                buffer[i] = sc->cl_reg->cl_rdr;
                   1282:                        if (NULL == tp) {
                   1283:                                /*
                   1284:                                 * if the channel is not configured,
                   1285:                                 * dont send characters upstream.
                   1286:                                 * also fix problem with NULL dereference
                   1287:                                 */
                   1288:                                reoir = 0;
                   1289:                                break;
                   1290:                        }
                   1291:
                   1292:                        sc->cl_reg->cl_reoir = reoir;
                   1293:                        for (i = 0; i < fifocnt; i++) {
                   1294:                                u_char c = buffer[i];
                   1295:
                   1296:                                /* does any restricitions exist on spl for this call */
                   1297:                                (*linesw[tp->t_line].l_rint)(c, tp);
                   1298:                                reoir = 0;
                   1299:                        }
                   1300:                        break;
                   1301:                default:
                   1302:                        log(LOG_WARNING, "cl_rxintr unknown mode %x\n", cmr);
                   1303:                        /* we probably will go to hell quickly now */
                   1304:                        reoir = REOIR_NOTRANSF;
                   1305:                        break;
                   1306:                }
                   1307:        }
                   1308:        sc->cl_reg->cl_reoir = reoir;
                   1309:        return (1);
                   1310: }
                   1311:
                   1312: void
                   1313: cl_overflow (sc, channel, ptime, msg)
                   1314: struct wlsoftc *sc;
                   1315: int channel;
                   1316: long *ptime;
                   1317: u_char *msg;
                   1318: {
                   1319: /*
                   1320:        if (*ptime != time.tv_sec) {
                   1321: */
                   1322:        {
                   1323: /*
                   1324:                *ptime = time.tv_sec;
                   1325: */
                   1326:                log(LOG_WARNING, "%s%d[%d]: %s overrun\n", wl_cd.cd_name,
                   1327:                        0 /* fix */, channel, msg);
                   1328:        }
                   1329: }
                   1330:
                   1331: void
                   1332: cl_parity (sc, channel)
                   1333:        struct wlsoftc *sc;
                   1334:        int channel;
                   1335: {
                   1336:        log(LOG_WARNING, "%s%d[%d]: parity error\n", wl_cd.cd_name, 0, channel);
                   1337: }
                   1338:
                   1339: void
                   1340: cl_frame (sc, channel)
                   1341:        struct wlsoftc *sc;
                   1342:        int channel;
                   1343: {
                   1344:        log(LOG_WARNING, "%s%d[%d]: frame error\n", wl_cd.cd_name, 0, channel);
                   1345: }
                   1346:
                   1347: void
                   1348: cl_break (sc, channel)
                   1349:        struct wlsoftc *sc;
                   1350:        int channel;
                   1351: {
                   1352:        log(LOG_WARNING, "%s%d[%d]: break detected\n", wl_cd.cd_name, 0, channel);
                   1353: }
                   1354:
                   1355: void
                   1356: cl_dumpport0()
                   1357: {
                   1358:        cl_dumpport(0);
                   1359: }
                   1360:
                   1361: void
                   1362: cl_dumpport1()
                   1363: {
                   1364:        cl_dumpport(1);
                   1365: }
                   1366:
                   1367: void
                   1368: cl_dumpport2()
                   1369: {
                   1370:        cl_dumpport(2);
                   1371: }
                   1372:
                   1373: void
                   1374: cl_dumpport3()
                   1375: {
                   1376:        cl_dumpport(3);
                   1377: }
                   1378:
                   1379: void
                   1380: cl_dumpport(channel)
                   1381:        int channel;
                   1382: {
                   1383:        u_char  livr, cmr, cor1, cor2, cor3, cor4, cor5, cor6, cor7,
                   1384:                schr1, schr2, schr3, schr4, scrl, scrh, lnxt,
                   1385:                rbpr, rcor, tbpr, tcor, rpilr, rir, tpr, ier, ccr,
                   1386:                dmabsts, arbsts, brbsts, atbsts, btbsts,
                   1387:                csr, rts, dtr, rtprl, rtprh;
                   1388:        volatile void * parbadru, *parbadrl,  *parbsts, *parbcnt;
                   1389:        u_short rcbadru, rcbadrl, arbadru, arbadrl, arbcnt,
                   1390:                brbadru, brbadrl, brbcnt;
                   1391:        u_short tcbadru, tcbadrl, atbadru, atbadrl, atbcnt,
                   1392:                btbadru, btbadrl, btbcnt;
                   1393:        struct wlsoftc *sc;
                   1394:
                   1395:        struct clreg *cl_reg;
                   1396:        int s;
                   1397:
                   1398:        sc = (struct wlsoftc *) wl_cd.cd_devs[0];
                   1399:        cl_reg = sc->cl_reg;
                   1400:
                   1401:        s = splcl();
                   1402:        cl_reg->cl_car  = (u_char) channel;
                   1403:        livr = cl_reg->cl_livr;
                   1404:        cmr = cl_reg->cl_cmr;
                   1405:        cor1 = cl_reg->cl_cor1;
                   1406:        cor2 = cl_reg->cl_cor2;
                   1407:        cor3 = cl_reg->cl_cor3;
                   1408:        cor4 = cl_reg->cl_cor4;
                   1409:        cor5 = cl_reg->cl_cor5;
                   1410:        cor6 = cl_reg->cl_cor6;
                   1411:        cor7 = cl_reg->cl_cor7;
                   1412:        schr1 = cl_reg->cl_schr1;
                   1413:        schr2 = cl_reg->cl_schr2;
                   1414:        schr3 = cl_reg->cl_schr3;
                   1415:        schr4 = cl_reg->cl_schr4;
                   1416:        scrl = cl_reg->cl_scrl;
                   1417:        scrh = cl_reg->cl_scrh;
                   1418:        lnxt = cl_reg->cl_lnxt;
                   1419:        rbpr = cl_reg->cl_rbpr;
                   1420:        rcor = cl_reg->cl_rcor;
                   1421:        tbpr = cl_reg->cl_tbpr;
                   1422:        rpilr = cl_reg->cl_rpilr;
                   1423:        ier = cl_reg->cl_ier;
                   1424:        ccr = cl_reg->cl_ccr;
                   1425:        tcor = cl_reg->cl_tcor;
                   1426:        csr = cl_reg->cl_csr;
                   1427:        tpr = cl_reg->cl_tpr;
                   1428:        rts = cl_reg->cl_msvr_rts;
                   1429:        dtr = cl_reg->cl_msvr_dtr;
                   1430:        rtprl = cl_reg->cl_rtprl;
                   1431:        rtprh = cl_reg->cl_rtprh;
                   1432:        dmabsts = cl_reg->cl_dmabsts;
                   1433:        tcbadru = cl_reg->cl_tcbadru;
                   1434:        tcbadrl = cl_reg->cl_tcbadrl;
                   1435:        rcbadru = cl_reg->cl_rcbadru;
                   1436:        rcbadrl = cl_reg->cl_rcbadrl;
                   1437:
                   1438:        parbadru = &(cl_reg->cl_arbadru);
                   1439:        parbadrl = &(cl_reg->cl_arbadrl);
                   1440:        parbcnt  = &(cl_reg->cl_arbcnt);
                   1441:        parbsts  = &(cl_reg->cl_arbsts);
                   1442:
                   1443:        arbadru = cl_reg->cl_arbadru;
                   1444:        arbadrl = cl_reg->cl_arbadrl;
                   1445:        arbcnt  = cl_reg->cl_arbcnt;
                   1446:        arbsts  = cl_reg->cl_arbsts;
                   1447:
                   1448:        brbadru = cl_reg->cl_brbadru;
                   1449:        brbadrl = cl_reg->cl_brbadrl;
                   1450:        brbcnt  = cl_reg->cl_brbcnt;
                   1451:        brbsts  = cl_reg->cl_brbsts;
                   1452:
                   1453:        atbadru = cl_reg->cl_atbadru;
                   1454:        atbadrl = cl_reg->cl_atbadrl;
                   1455:        atbcnt  = cl_reg->cl_atbcnt;
                   1456:        atbsts  = cl_reg->cl_atbsts;
                   1457:
                   1458:        btbadru = cl_reg->cl_btbadru;
                   1459:        btbadrl = cl_reg->cl_btbadrl;
                   1460:        btbcnt  = cl_reg->cl_btbcnt;
                   1461:        btbsts  = cl_reg->cl_btbsts;
                   1462:
                   1463:        splx(s);
                   1464:
                   1465:        printf("{ port %x livr %x cmr %x\n",
                   1466:                  channel,livr,   cmr);
                   1467:        printf("cor1 %x cor2 %x cor3 %x cor4 %x cor5 %x cor6 %x cor7 %x\n",
                   1468:                cor1,   cor2,   cor3,   cor4,   cor5,   cor6,   cor7);
                   1469:        printf("schr1 %x schr2 %x schr3 %x schr4 %x\n",
                   1470:                schr1,   schr2,   schr3,   schr4);
                   1471:        printf("scrl %x scrh %x lnxt %x\n",
                   1472:                scrl,   scrh,   lnxt);
                   1473:        printf("rbpr %x rcor %x tbpr %x tcor %x\n",
                   1474:                rbpr,   rcor,   tbpr,   tcor);
                   1475:        printf("rpilr %x rir %x ier %x ccr %x\n",
                   1476:                rpilr,   rir,   ier,   ccr);
                   1477:        printf("tpr %x csr %x rts %x dtr %x\n",
                   1478:                tpr,   csr,   rts,   dtr);
                   1479:        printf("rtprl %x rtprh %x\n",
                   1480:                rtprl,   rtprh);
                   1481:        printf("rxcnt %x txcnt %x\n",
                   1482:                sc->sc_cl[channel].rxcnt, sc->sc_cl[channel].txcnt);
                   1483:        printf("dmabsts %x, tcbadru %x, tcbadrl %x, rcbadru %x, rcbadrl %x,\n",
                   1484:                dmabsts,    tcbadru,    tcbadrl,    rcbadru,    rcbadrl );
                   1485:        printf("parbadru %x, parbadrl %x, parbcnt %x, parbsts %x\n",
                   1486:                parbadru,    parbadrl,    parbcnt,    parbsts);
                   1487:        printf("arbadru %x, arbadrl %x, arbcnt %x, arbsts %x\n",
                   1488:                arbadru,    arbadrl,    arbcnt,    arbsts);
                   1489:        printf("brbadru %x, brbadrl %x, brbcnt %x, brbsts %x\n",
                   1490:                brbadru,    brbadrl,    brbcnt,    brbsts);
                   1491:        printf("atbadru %x, atbadrl %x, atbcnt %x, atbsts %x\n",
                   1492:                atbadru,    atbadrl,    atbcnt,    atbsts);
                   1493:        printf("btbadru %x, btbadrl %x, btbcnt %x, btbsts %x\n",
                   1494:                btbadru,    btbadrl,    btbcnt,    btbsts);
                   1495:        printf("}\n");
                   1496: }
                   1497:
                   1498: static void
                   1499: clputc(sc, unit, c)
                   1500:        struct wlsoftc *sc;
                   1501:        int unit;
                   1502:        u_char c;
                   1503: {
                   1504:        int s;
                   1505:        u_char schar;
                   1506:        u_char oldchannel;
                   1507:        struct clreg *cl_reg;
                   1508:        cl_reg = sc->cl_reg;
                   1509:
                   1510:        s = splhigh();
                   1511:        oldchannel = cl_reg->cl_car;
                   1512:        cl_reg->cl_car = unit;
                   1513:        if (cl_reg->cl_tftc > 0) {
                   1514:                cl_reg->cl_tdr = c;
                   1515:        }
                   1516:        cl_reg->cl_car = oldchannel;
                   1517:        splx(s);
                   1518: }

CVSweb