diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-01 18:13:17 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-01 18:13:17 +0000 |
commit | ba2671a1203ff5f02f59aae6a0bfee14ef071085 (patch) | |
tree | a2bd476a4d48e793bc783a77840baf76740ba6a0 /sys/arch | |
parent | 7962a199da906f0ef3973d6ea8f9762c4e47105d (diff) |
fixed ddb, improved fifo handling, new still-not-working dma support
from drahn@pacific.urbana.mcd.mot.com
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/mvme68k/dev/cl.c | 481 | ||||
-rw-r--r-- | sys/arch/mvme68k/dev/clreg.h | 238 |
2 files changed, 510 insertions, 209 deletions
diff --git a/sys/arch/mvme68k/dev/cl.c b/sys/arch/mvme68k/dev/cl.c index f6f384f2a4b..12b1184965d 100644 --- a/sys/arch/mvme68k/dev/cl.c +++ b/sys/arch/mvme68k/dev/cl.c @@ -1,4 +1,4 @@ -/* $Id: cl.c,v 1.4 1995/11/19 03:04:16 chuck Exp $ */ +/* $Id: cl.c,v 1.5 1995/12/01 18:13:15 deraadt Exp $ */ /* * Copyright (c) 1995 Dale Rahn. All rights reserved. @@ -30,6 +30,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* DMA mode still does not work!!! */ + #include <sys/param.h> #include <sys/callout.h> #include <sys/conf.h> @@ -62,12 +64,16 @@ #define CL_FIFO_CNT 0xc #define CL_RX_TIMEOUT 0x10 -#define CL_DMAMODE 0x1 -#define CL_INTRMODE 0x0 +#define CL_RXDMAINT 0x82 +#define CL_TXDMAINT 0x42 +#define CL_TXMASK 0x47 +#define CL_RXMASK 0x87 +#define CL_TXINTR 0x02 +#define CL_RXINTR 0x02 struct cl_cons { u_char *cl_paddr; - volatile struct clreg *cl_vaddr; + struct clreg *cl_vaddr; volatile struct pcctworeg *pcctwoaddr; u_char channel; } cl_cons; @@ -86,8 +92,20 @@ struct cl_info { u_char transmitting; u_long txcnt; u_long rxcnt; + + void *rx[2]; + void *rxp[2]; + void *tx[2]; + void *txp[2]; }; #define CLCD_PORTS_PER_CHIP 4 +#define CL_BUFSIZE 256 + +#ifndef DO_MALLOC +/* four (4) buffers per port */ +char cl_dmabuf [CLCD_PORTS_PER_CHIP * CL_BUFSIZE * 4]; +#endif + struct clsoftc { struct device sc_dev; struct evcnt sc_txintrcnt; @@ -96,7 +114,7 @@ struct clsoftc { time_t sc_rotime; /* time of last ring overrun */ time_t sc_fotime; /* time of last fifo overrun */ u_char *pbase; - volatile struct clreg *cl_reg; + struct clreg *cl_reg; struct cl_info sc_cl[CLCD_PORTS_PER_CHIP]; struct intrhand sc_ih_e; struct intrhand sc_ih_m; @@ -133,7 +151,7 @@ struct { int clcnprobe __P((struct consdev *cp)); int clcninit __P((struct consdev *cp)); int clcngetc __P((dev_t dev)); -int clcnputc __P((dev_t dev, char c)); +int clcnputc __P((dev_t dev, u_char c)); u_char cl_clkdiv __P((int speed)); u_char cl_clknum __P((int speed)); u_char cl_clkrxtimeout __P((int speed)); @@ -145,7 +163,7 @@ int clparam __P((struct tty *tp, struct termios *t)); int cl_mintr __P((struct clsoftc *sc)); int cl_txintr __P((struct clsoftc *sc)); int cl_rxintr __P((struct clsoftc *sc)); -void cl_overflow __P((struct clsoftc *sc, int channel, long *ptime, char *msg)); +void cl_overflow __P((struct clsoftc *sc, int channel, long *ptime, u_char *msg)); void cl_parity __P((struct clsoftc *sc, int channel)); void cl_frame __P((struct clsoftc *sc, int channel)); void cl_break __P(( struct clsoftc *sc, int channel)); @@ -163,7 +181,7 @@ int clioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)); int clstop __P((struct tty *tp, int flag)); static void cl_initchannel __P((struct clsoftc *sc, int channel)); -static void clputc __P((struct clsoftc *sc, int unit, char c)); +static void clputc __P((struct clsoftc *sc, int unit, u_char c)); static u_char clgetc __P((struct clsoftc *sc, int *channel)); static void cloutput __P( (struct tty *tp)); @@ -204,7 +222,7 @@ int clprobe(parent, self, aux) * should be previously configured, * we can check the value before resetting the chip */ - volatile struct clreg *cl_reg; + struct clreg *cl_reg; struct confargs *ca = aux; int ret; if (cputyp != CPU_167 && cputyp != CPU_166 @@ -253,7 +271,39 @@ clattach(parent, self, aux) sc->cl_reg->cl_tpilr = 0x02; sc->cl_reg->cl_mpilr = 0x01; +#ifdef DO_MALLOC + sc->sc_cl[0].rx[0] = (void *)(dvma_malloc(16 * CL_BUFSIZE)); +#else + sc->sc_cl[0].rx[0] = (void *) (&cl_dmabuf); +#endif + sc->sc_cl[0].rx[1] = (void *)(((int)sc->sc_cl[0].rx[0]) + CL_BUFSIZE); + sc->sc_cl[1].rx[0] = (void *)(((int)sc->sc_cl[0].rx[1]) + CL_BUFSIZE); + sc->sc_cl[1].rx[1] = (void *)(((int)sc->sc_cl[1].rx[0]) + CL_BUFSIZE); + + sc->sc_cl[2].rx[0] = (void *)(((int)sc->sc_cl[1].rx[1]) + CL_BUFSIZE); + sc->sc_cl[2].rx[1] = (void *)(((int)sc->sc_cl[2].rx[0]) + CL_BUFSIZE); + sc->sc_cl[3].rx[0] = (void *)(((int)sc->sc_cl[2].rx[1]) + CL_BUFSIZE); + sc->sc_cl[3].rx[1] = (void *)(((int)sc->sc_cl[3].rx[0]) + CL_BUFSIZE); + + sc->sc_cl[0].tx[0] = (void *)(((int)sc->sc_cl[3].rx[1]) + CL_BUFSIZE); + sc->sc_cl[0].tx[1] = (void *)(((int)sc->sc_cl[0].tx[0]) + CL_BUFSIZE); + sc->sc_cl[1].tx[0] = (void *)(((int)sc->sc_cl[0].tx[1]) + CL_BUFSIZE); + sc->sc_cl[1].tx[1] = (void *)(((int)sc->sc_cl[1].tx[0]) + CL_BUFSIZE); + + sc->sc_cl[2].tx[0] = (void *)(((int)sc->sc_cl[1].tx[1]) + CL_BUFSIZE); + sc->sc_cl[2].tx[1] = (void *)(((int)sc->sc_cl[2].tx[0]) + CL_BUFSIZE); + sc->sc_cl[3].tx[0] = (void *)(((int)sc->sc_cl[2].tx[1]) + CL_BUFSIZE); + sc->sc_cl[3].tx[1] = (void *)(((int)sc->sc_cl[3].tx[0]) + CL_BUFSIZE); for (i = 0; i < CLCD_PORTS_PER_CHIP; i++) { + int j; + for (j = 0; j < 2 ; j++) { + sc->sc_cl[i].rxp[j] = (void *)kvtop(sc->sc_cl[i].rx[j]); +printf("cl[%d].rxbuf[%d] %x p %x\n", + i, j, sc->sc_cl[i].rx[j], sc->sc_cl[i].rxp[j]); + sc->sc_cl[i].txp[j] = (void *)kvtop(sc->sc_cl[i].tx[j]); +printf("cl[%d].txbuf[%d] %x p %x\n", + i, j, sc->sc_cl[i].tx[j], sc->sc_cl[i].txp[j]); + } #if 0 sc->sc_cl[i].cl_rxmode = !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x01)); @@ -315,15 +365,14 @@ cl_initchannel(sc, channel) int channel; { int s; - volatile struct clreg *cl_reg = sc->cl_reg; + struct clreg *cl_reg = sc->cl_reg; /* set up option registers */ sc->sc_cl[channel].tty = NULL; s = splhigh(); - cl_reg->cl_car = (char) channel; + cl_reg->cl_car = (u_char) channel; /* async, do we want to try DMA at some point? */ cl_reg->cl_livr = PCC2_VECBASE + 0xc;/* set vector base at 5C */ cl_reg->cl_ier = 0x88; /* should change XXX */ - cl_reg->cl_licr = 0x00; /* will change if DMA support XXX */ /* if the port is not the console */ if (sc->sc_cl[channel].cl_consio != 1) { cl_reg->cl_cmr = 0x02; @@ -351,6 +400,18 @@ cl_initchannel(sc, channel) cl_reg->cl_rtprl = CL_RX_TIMEOUT; cl_reg->cl_rtprh = 0x00; } + if (channel == 2) { /* test one channel now */ + /* shift for tx DMA */ + /* no shift for rx DMA */ + /* async only */ + /* rx only (tx commented out) */ + cl_reg->cl_cmr = /* CL_TXDMAINT | */ CL_RXDMAINT; + cl_reg->cl_ier = 0xa8; + cl_reg->cl_licr = 0x00; + } + sc->cl_reg->cl_ccr = 0x20; + while (sc->cl_reg->cl_ccr != 0) { + } splx(s); } @@ -513,6 +574,48 @@ int clopen (dev, flag, mode, p) } #endif tp->t_state |= TS_CARR_ON; +#ifdef CL_DMA_WORKS + { + u_char save = sc->cl_reg->cl_car; + sc->cl_reg->cl_car = channel; + sc->cl_reg->cl_arbadrl = + ((u_long)sc->sc_cl[channel].rxp[0]) & 0xffff; + sc->cl_reg->cl_arbadru = + ((u_long)sc->sc_cl[channel].rxp[0]) >> 16; + sc->cl_reg->cl_brbadrl = + ((u_long)sc->sc_cl[channel].rxp[1]) & 0xffff; + sc->cl_reg->cl_brbadru = + ((u_long)sc->sc_cl[channel].rxp[1]) >> 16; + sc->cl_reg->cl_atbadrl = + ((u_long)sc->sc_cl[channel].txp[0]) & 0xffff; + sc->cl_reg->cl_atbadru = + ((u_long)sc->sc_cl[channel].txp[0]) >> 16; + sc->cl_reg->cl_btbadrl = + ((u_long)sc->sc_cl[channel].txp[1]) & 0xffff; + sc->cl_reg->cl_btbadru = + ((u_long)sc->sc_cl[channel].txp[1]) >> 16; + sc->cl_reg->cl_arbcnt = CL_BUFSIZE; + sc->cl_reg->cl_brbcnt = CL_BUFSIZE; + sc->cl_reg->cl_arbsts = 0x01; + sc->cl_reg->cl_brbsts = 0x01; +if (channel == 2) { /* test one channel now */ + /* shift for tx DMA */ + /* no shift for rx DMA */ +#if 0 + /* tx only */ + sc->cl_reg->cl_licr = (CL_DMAMODE << 4); + sc->cl_reg->cl_cmr = 0x42; +#endif + /* rx only */ + sc->cl_reg->cl_licr = 0x00; + sc->cl_reg->cl_cmr = 0x82; +} + sc->cl_reg->cl_ccr = 0x20; + while (sc->cl_reg->cl_ccr != 0) { + } + sc->cl_reg->cl_car = save; + } +#endif /* CL_DMA_WORKS */ } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { splx(s); return(EBUSY); @@ -566,11 +669,11 @@ void cloutput(tp) struct tty *tp; { int cc, s, unit, cnt; - char *tptr; + u_char *tptr; int channel; struct clsoftc *sc; dev_t dev; - char cl_obuffer[CLCDBUF+1]; + u_char cl_obuffer[CLCDBUF+1]; dev = tp->t_dev; unit = CL_UNIT(dev); @@ -807,7 +910,7 @@ struct consdev *cp; int size = (0x1ff + PGOFSET) & ~PGOFSET; int pcc2_size = (0x3C + PGOFSET) & ~PGOFSET; #endif - volatile struct clreg *cl_reg; + struct clreg *cl_reg; cl_cons.cl_paddr = (void *)0xfff45000; #ifdef MAP_DOES_WORK @@ -854,7 +957,7 @@ int cl_instat(sc) struct clsoftc *sc; { - volatile struct clreg *cl_reg; + struct clreg *cl_reg; if ( NULL == sc) { cl_reg = cl_cons.cl_vaddr; } else { @@ -868,7 +971,7 @@ clcngetc(dev) { u_char val, reoir, licr, isrl, data, status, fifo_cnt; int got_char = 0; - volatile struct clreg *cl_reg = cl_cons.cl_vaddr; + struct clreg *cl_reg = cl_cons.cl_vaddr; volatile struct pcctworeg *pcc2_base = cl_cons.pcctwoaddr; while (got_char == 0) { val = cl_reg->cl_rir; @@ -915,7 +1018,7 @@ clcngetc(dev) int clcnputc(dev, c) dev_t dev; - char c; + u_char c; { /* is this the correct location for the cr -> cr/lf tranlation? */ if (c == '\n') @@ -939,12 +1042,12 @@ static void clputc(sc, unit, c) struct clsoftc *sc; int unit; - char c; + u_char c; { int s; u_char schar; u_char oldchannel; - volatile struct clreg *cl_reg; + struct clreg *cl_reg; if (0 == sc) { /* output on console */ cl_reg = cl_cons.cl_vaddr; @@ -1042,7 +1145,7 @@ clgetc(sc, channel) struct clsoftc *sc; int *channel; { - volatile struct clreg *cl_reg; + struct clreg *cl_reg; volatile struct pcctworeg *pcc2_base; u_char val, reoir, licr, isrl, fifo_cnt, data; if (0 == sc) { @@ -1145,14 +1248,23 @@ clccparam(sc, par, channel) } sc->cl_reg->cl_cor3 = par->c_cflag & PARENB ? 4 : 2; - if (par->c_cflag & PARENB) { - if (par->c_cflag & PARODD) { - sc->cl_reg->cl_cor1 = 0xE0 | clen ; /* odd */ + { + u_char cor1; + if (par->c_cflag & PARENB) { + if (par->c_cflag & PARODD) { + cor1 = 0xE0 | clen ; /* odd */ + } else { + cor1 = 0x40 | clen ; /* even */ + } } else { - sc->cl_reg->cl_cor1 = 0x40 | clen ; /* even */ + cor1 = 0x10 | clen; /* ignore parity */ + } + if (sc->cl_reg->cl_cor1 != cor1) { + sc->cl_reg->cl_cor1 = cor1; + sc->cl_reg->cl_ccr = 0x20; + while (sc->cl_reg->cl_ccr != 0) { + } } - } else { - sc->cl_reg->cl_cor1 = 0x10 | clen; /* ignore parity */ } if (sc->sc_cl[channel].cl_consio == 0 @@ -1162,6 +1274,8 @@ clccparam(sc, par, channel) } else { sc->cl_reg->cl_ccr = 0x0a; } + while (sc->cl_reg->cl_ccr != 0) { + } ints = 0; #define SCC_DSR 0x80 #define SCC_DCD 0x40 @@ -1308,7 +1422,7 @@ cl_mintr(sc) struct tty *tp; if(((mir = sc->cl_reg->cl_mir) & 0x40) == 0x0) { /* only if intr is not shared? */ - printf("cl_mintr extra intr\n"); + log(LOG_WARNING, "cl_mintr extra intr\n"); return 0; } sc->sc_mxintrcnt.ev_count++; @@ -1318,26 +1432,26 @@ cl_mintr(sc) msvr = sc->cl_reg->cl_msvr_rts; if (misr & 0x01) { /* timers are not currently used?? */ - printf ("cl_mintr: channel %x timer 1 unexpected\n",channel); + log(LOG_WARNING, "cl_mintr: channel %x timer 1 unexpected\n",channel); } if (misr & 0x02) { /* timers are not currently used?? */ - printf ("cl_mintr: channel %x timer 2 unexpected\n",channel); + log(LOG_WARNING, "cl_mintr: channel %x timer 2 unexpected\n",channel); } if (misr & 0x20) { - printf ("cl_mintr: channel %x cts %x\n",channel, + log(LOG_WARNING, "cl_mintr: channel %x cts %x\n",channel, ((msvr & 0x20) != 0x0) ); } if (misr & 0x40) { struct tty *tp = sc->sc_cl[channel].tty; - printf ("cl_mintr: channel %x cd %x\n",channel, + log(LOG_WARNING, "cl_mintr: channel %x cd %x\n",channel, ((msvr & 0x40) != 0x0) ); ttymodem(tp, ((msvr & 0x40) != 0x0) ); } if (misr & 0x80) { - printf ("cl_mintr: channel %x dsr %x\n",channel, + log(LOG_WARNING, "cl_mintr: channel %x dsr %x\n",channel, ((msvr & 0x80) != 0x0) ); } @@ -1350,7 +1464,7 @@ cl_txintr(sc) struct clsoftc *sc; { static empty = 0; - u_char tir, licr, teoir; + u_char tir, cmr, teoir; u_char max; int channel; struct tty *tp; @@ -1359,13 +1473,13 @@ cl_txintr(sc) u_char *tptr; if(((tir = sc->cl_reg->cl_tir) & 0x40) == 0x0) { /* only if intr is not shared ??? */ - printf ("cl_txintr extra intr\n"); + log(LOG_WARNING, "cl_txintr extra intr\n"); return 0; } sc->sc_txintrcnt.ev_count++; channel = tir & 0x03; - licr = sc->cl_reg->cl_licr; + cmr = sc->cl_reg->cl_cmr; sc->sc_cl[channel].txcnt ++; @@ -1374,11 +1488,62 @@ cl_txintr(sc) sc->cl_reg->cl_teoir = 0x08; return 1; } - switch ((licr >> 4)& 0x3) { - case CL_DMAMODE: - teoir = 0x08; + switch (cmr & CL_TXMASK) { + case CL_TXDMAINT: + { + u_char dmabsts; + int nbuf, busy, resid; + void *pbuffer; + dmabsts = sc->cl_reg->cl_dmabsts; + log(LOG_WARNING, "cl_txintr: DMAMODE channel %x dmabsts %x\n", + channel, dmabsts); + nbuf = ((dmabsts & 0x8) >> 3) & 0x1; + busy = ((dmabsts & 0x4) >> 2) & 0x1; + + do { + pbuffer = sc->sc_cl[channel].tx[nbuf]; + resid = tp->t_outq.c_cc; + cnt = min (CL_BUFSIZE,resid); + log(LOG_WARNING, "cl_txintr: resid %x cnt %x pbuf %x\n", + resid, cnt, pbuffer); + if (cnt != 0) { + cnt = q_to_b(&tp->t_outq, pbuffer, cnt); + resid -= cnt; + if (nbuf == 0) { + sc->cl_reg->cl_atbadru = + ((u_long) sc->sc_cl[channel].txp[nbuf]) >> 16; + sc->cl_reg->cl_atbadrl = + ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff; + sc->cl_reg->cl_atbcnt = cnt; + sc->cl_reg->cl_atbsts = 0x43; + } else { + sc->cl_reg->cl_btbadru = + ((u_long) sc->sc_cl[channel].txp[nbuf]) >> 16; + sc->cl_reg->cl_btbadrl = + ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff; + sc->cl_reg->cl_btbcnt = cnt; + sc->cl_reg->cl_btbsts = 0x43; + } + teoir = 0x08; + } else { + teoir = 0x08; + if (tp->t_state & TS_BUSY) { + tp->t_state &= ~(TS_BUSY | TS_FLUSH); + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t) &tp->t_outq); + } + selwakeup(&tp->t_wsel); + } + sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~0x3; + } + nbuf = ~nbuf & 0x1; + busy--; + } while (resid != 0 && busy != -1);/* if not busy do other buffer */ + log(LOG_WARNING, "cl_txintr: done\n"); + } break; - case CL_INTRMODE: + case CL_TXINTR: max = sc->cl_reg->cl_tftc; cnt = min ((int)max,tp->t_outq.c_cc); if (cnt != 0) { @@ -1390,7 +1555,7 @@ cl_txintr(sc) teoir = 0x00; } else { if (empty > 5 && ((empty % 20000 )== 0)) { - printf("cl_txintr to many empty intr %d channel %d\n", + log(LOG_WARNING, "cl_txintr to many empty intr %d channel %d\n", empty, channel); } empty++; @@ -1407,7 +1572,7 @@ cl_txintr(sc) } break; default: - printf("cl_txintr unknown mode %x\n", ((licr >> 4) & 0x3)); + log(LOG_WARNING, "cl_txintr unknown mode %x\n", cmr); /* we probably will go to hell quickly now */ teoir = 0x08; } @@ -1419,75 +1584,160 @@ int cl_rxintr(sc) struct clsoftc *sc; { - u_char rir, channel, licr, risrl; + u_char rir, channel, cmr, risrl; u_char c; u_char fifocnt; struct tty *tp; int i; u_char reoir; + u_char buffer[CL_FIFO_MAX +1]; rir = sc->cl_reg->cl_rir; if((rir & 0x40) == 0x0) { /* only if intr is not shared ??? */ - printf ("cl_rxintr extra intr\n"); + log(LOG_WARNING, "cl_rxintr extra intr\n"); return 0; } sc->sc_rxintrcnt.ev_count++; channel = rir & 0x3; - licr = sc->cl_reg->cl_licr; + cmr = sc->cl_reg->cl_cmr; reoir = 0x08; sc->sc_cl[channel].rxcnt ++; - - switch (licr & 0x03) { - case CL_DMAMODE: + risrl = sc->cl_reg->cl_risrl; + if (risrl & 0x80) { + /* timeout, no characters */ reoir = 0x08; + } else + /* We don't need no sinkin special characters */ + if (risrl & 0x08) { + cl_overflow (sc, channel, &sc->sc_fotime, "fifo"); + reoir = 0x08; + } else + if (risrl & 0x04) { + cl_parity(sc, channel); + reoir = 0x08; + } else + if (risrl & 0x02) { + cl_frame(sc, channel); + reoir = 0x08; + } else + if (risrl & 0x01) { + cl_break(sc, channel); + reoir = 0x08; + } + + switch (cmr & CL_RXMASK) { + case CL_RXDMAINT: + { + int nbuf; + u_short cnt; + int bufcomplete; + u_char status, dmabsts; + u_char risrh = sc->cl_reg->cl_risrh; + dmabsts = sc->cl_reg->cl_dmabsts; +#ifdef DMA_DEBUG +log(LOG_WARNING, "cl_txintr: DMAMODE channel %x dmabsts %x risrl %x risrh %x\n", + channel, dmabsts, risrl, risrh); +#endif + nbuf = (risrh & 0x08) ? 1 : 0; + bufcomplete = (risrh & 0x20) ? 1 : 0; + if (nbuf == 0) { + cnt = sc->cl_reg->cl_arbcnt; + status = sc->cl_reg->cl_arbsts; + } else { + cnt = sc->cl_reg->cl_brbcnt; + status = sc->cl_reg->cl_brbsts; + } +#ifdef DMA_DEBUG +log(LOG_WARNING, "cl_rxintr: 1channel %x buf %x cnt %x status %x\n", +channel, nbuf, cnt, status); +#endif +#if USE_BUFFER + cl_appendbufn(sc, channel, sc->rx[nbuf], cnt); +#else + { + int i; + u_char *pbuf; + tp = sc->sc_cl[channel].tty; + pbuf = sc->sc_cl[channel].rx[nbuf]; + /* this should be done at off level */ +{ + u_short rcbadru, rcbadrl; + u_char arbsts, brbsts; + u_char *pbufs, *pbufe; + rcbadru = sc->cl_reg->cl_rcbadru; + rcbadrl = sc->cl_reg->cl_rcbadrl; + arbsts = sc->cl_reg->cl_arbsts; + brbsts = sc->cl_reg->cl_brbsts; + pbufs = sc->sc_cl[channel].rxp[nbuf]; + pbufe = (u_char *)(((u_long)rcbadru << 16) | (u_long)rcbadrl); + cnt = pbufe - pbufs; +#ifdef DMA_DEBUG + log(LOG_WARNING, "cl_rxintr: rcbadru %x rcbadrl %x arbsts %x brbsts %x cnt %x\n", + rcbadru, rcbadrl, arbsts, brbsts, cnt); +#endif +#ifdef DMA_DEBUG1 + log(LOG_WARNING, "cl_rxintr: buf %x cnt %x\n", + nbuf, cnt); +#endif +} + reoir = 0x0 | (bufcomplete) ? 0 : 0xd0; + sc->cl_reg->cl_reoir = reoir; +#ifdef DMA_DEBUG +log(LOG_WARNING, "cl_rxintr: reoir %x\n", reoir); +#endif + delay(10); /* give the chip a moment */ +#ifdef DMA_DEBUG +log(LOG_WARNING, "cl_rxintr: 2channel %x buf %x cnt %x status %x\n", +channel, nbuf, cnt, status); +#endif + for (i = 0; i < cnt; i++) { + u_char c; + c = pbuf[i]; + (*linesw[tp->t_line].l_rint)(c,tp); + } + /* this should be done at off level */ + if (nbuf == 0) { + sc->cl_reg->cl_arbcnt = CL_BUFSIZE; + sc->cl_reg->cl_arbsts = 0x01; + } else { + sc->cl_reg->cl_brbcnt = CL_BUFSIZE; + sc->cl_reg->cl_brbsts = 0x01; + } + } +#endif + } + sc->cl_reg->cl_reoir = reoir; break; - case CL_INTRMODE: - risrl = sc->cl_reg->cl_risrl; - if (risrl & 0x80) { - /* timeout, no characters */ - reoir = 0x08; - } else - /* We don't need no sinkin special characters */ - if (risrl & 0x08) { - cl_overflow (sc, channel, &sc->sc_fotime, "fifo"); - reoir = 0x08; - } else - if (risrl & 0x04) { - cl_parity(sc, channel); - reoir = 0x08; - } else - if (risrl & 0x02) { - cl_frame(sc, channel); - reoir = 0x08; - } else - if (risrl & 0x01) { - cl_break(sc, channel); - reoir = 0x08; - } else { - fifocnt = sc->cl_reg->cl_rfoc; - tp = sc->sc_cl[channel].tty; - for (i = 0; i < fifocnt; i++) { - c = sc->cl_reg->cl_rdr; + case CL_RXINTR: + fifocnt = sc->cl_reg->cl_rfoc; + tp = sc->sc_cl[channel].tty; + for (i = 0; i < fifocnt; i++) { + buffer[i] = sc->cl_reg->cl_rdr; + } + + sc->cl_reg->cl_reoir = reoir; + for (i = 0; i < fifocnt; i++) { + u_char c; + c = buffer[i]; #if USE_BUFFER - cl_appendbuf(sc, channel, c); + cl_appendbuf(sc, channel, c); #else - /* does any restricitions exist on spl - * for this call - */ - (*linesw[tp->t_line].l_rint)(c,tp); - reoir = 0x00; + /* does any restricitions exist on spl + * for this call + */ + (*linesw[tp->t_line].l_rint)(c,tp); + reoir = 0x00; #endif - } } break; default: - printf("cl_rxintr unknown mode %x\n",licr & 0x03); + log(LOG_WARNING, "cl_rxintr unknown mode %x\n", cmr); /* we probably will go to hell quickly now */ reoir = 0x08; + sc->cl_reg->cl_reoir = reoir; } - sc->cl_reg->cl_reoir = reoir; return 1; } @@ -1496,7 +1746,7 @@ cl_overflow (sc, channel, ptime, msg) struct clsoftc *sc; int channel; long *ptime; -char *msg; +u_char *msg; { /* if (*ptime != time.tv_sec) { @@ -1505,7 +1755,7 @@ char *msg; /* *ptime = time.tv_sec; */ - log(LOG_WARNING, "%s%d[%d]: %s overrun", clcd.cd_name, + log(LOG_WARNING, "%s%d[%d]: %s overrun\n", clcd.cd_name, 0 /* fix */, channel, msg); } return; @@ -1515,7 +1765,7 @@ cl_parity (sc, channel) struct clsoftc *sc; int channel; { - log(LOG_WARNING, "%s%d[%d]: parity error", clcd.cd_name, 0, channel); + log(LOG_WARNING, "%s%d[%d]: parity error\n", clcd.cd_name, 0, channel); return; } void @@ -1523,7 +1773,7 @@ cl_frame (sc, channel) struct clsoftc *sc; int channel; { - log(LOG_WARNING, "%s%d[%d]: frame error", clcd.cd_name, 0, channel); + log(LOG_WARNING, "%s%d[%d]: frame error\n", clcd.cd_name, 0, channel); return; } void @@ -1531,7 +1781,7 @@ cl_break (sc, channel) struct clsoftc *sc; int channel; { - log(LOG_WARNING, "%s%d[%d]: break detected", clcd.cd_name, 0, channel); + log(LOG_WARNING, "%s%d[%d]: break detected\n", clcd.cd_name, 0, channel); return; } @@ -1567,10 +1817,16 @@ cl_dumpport(channel) u_char livr, cmr, cor1, cor2, cor3, cor4, cor5, cor6, cor7, schr1, schr2, schr3, schr4, scrl, scrh, lnxt, rbpr, rcor, tbpr, tcor, rpilr, rir, tpr, ier, ccr, + dmabsts, arbsts, brbsts, atbsts, btbsts, csr, rts, dtr, rtprl, rtprh; + volatile void * parbadru, *parbadrl, *parbsts, *parbcnt; + u_short rcbadru, rcbadrl, arbadru, arbadrl, arbcnt, + brbadru, brbadrl, brbcnt; + u_short tcbadru, tcbadrl, atbadru, atbadrl, atbcnt, + btbadru, btbadrl, btbcnt; struct clsoftc *sc; - volatile struct clreg *cl_reg; + struct clreg *cl_reg; int s; cl_reg = cl_cons.cl_vaddr; @@ -1578,7 +1834,7 @@ cl_dumpport(channel) sc = (struct clsoftc *) clcd.cd_devs[0]; s = splcl(); - cl_reg->cl_car = (char) channel; + cl_reg->cl_car = (u_char) channel; livr = cl_reg->cl_livr; cmr = cl_reg->cl_cmr; cor1 = cl_reg->cl_cor1; @@ -1608,6 +1864,37 @@ cl_dumpport(channel) dtr = cl_reg->cl_msvr_dtr; rtprl = cl_reg->cl_rtprl; rtprh = cl_reg->cl_rtprh; + dmabsts = cl_reg->cl_dmabsts; + tcbadru = cl_reg->cl_tcbadru; + tcbadrl = cl_reg->cl_tcbadrl; + rcbadru = cl_reg->cl_rcbadru; + rcbadrl = cl_reg->cl_rcbadrl; + + parbadru = &(cl_reg->cl_arbadru); + parbadrl = &(cl_reg->cl_arbadrl); + parbcnt = &(cl_reg->cl_arbcnt); + parbsts = &(cl_reg->cl_arbsts); + + arbadru = cl_reg->cl_arbadru; + arbadrl = cl_reg->cl_arbadrl; + arbcnt = cl_reg->cl_arbcnt; + arbsts = cl_reg->cl_arbsts; + + brbadru = cl_reg->cl_brbadru; + brbadrl = cl_reg->cl_brbadrl; + brbcnt = cl_reg->cl_brbcnt; + brbsts = cl_reg->cl_brbsts; + + atbadru = cl_reg->cl_atbadru; + atbadrl = cl_reg->cl_atbadrl; + atbcnt = cl_reg->cl_atbcnt; + atbsts = cl_reg->cl_atbsts; + + btbadru = cl_reg->cl_btbadru; + btbadrl = cl_reg->cl_btbadrl; + btbcnt = cl_reg->cl_btbcnt; + btbsts = cl_reg->cl_btbsts; + splx(s); printf("{ port %x livr %x cmr %x\n", @@ -1628,6 +1915,18 @@ cl_dumpport(channel) rtprl, rtprh); printf("rxcnt %x txcnt %x\n", sc->sc_cl[channel].rxcnt, sc->sc_cl[channel].txcnt); + printf("dmabsts %x, tcbadru %x, tcbadrl %x, rcbadru %x, rcbadrl %x,\n", + dmabsts, tcbadru, tcbadrl, rcbadru, rcbadrl ); + printf("parbadru %x, parbadrl %x, parbcnt %x, parbsts %x\n", + parbadru, parbadrl, parbcnt, parbsts); + printf("arbadru %x, arbadrl %x, arbcnt %x, arbsts %x\n", + arbadru, arbadrl, arbcnt, arbsts); + printf("brbadru %x, brbadrl %x, brbcnt %x, brbsts %x\n", + brbadru, brbadrl, brbcnt, brbsts); + printf("atbadru %x, atbadrl %x, atbcnt %x, atbsts %x\n", + atbadru, atbadrl, atbcnt, atbsts); + printf("btbadru %x, btbadrl %x, btbcnt %x, btbsts %x\n", + btbadru, btbadrl, btbcnt, btbsts); printf("}\n"); return; } diff --git a/sys/arch/mvme68k/dev/clreg.h b/sys/arch/mvme68k/dev/clreg.h index b54c83fe920..6d02a4debb9 100644 --- a/sys/arch/mvme68k/dev/clreg.h +++ b/sys/arch/mvme68k/dev/clreg.h @@ -1,8 +1,8 @@ -/* $Id: clreg.h,v 1.2 1995/11/07 08:48:54 deraadt Exp $ */ +/* $Id: clreg.h,v 1.3 1995/12/01 18:13:16 deraadt Exp $ */ /* * Copyright (c) 1995 Dale Rahn. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by Dale Rahn. + * This product includes software developed by Dale Rahn. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * @@ -27,135 +27,137 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + */ struct clreg { - u_char anon1[0x7]; - u_char cl_cor7; /* 0x07 */ - u_char anon2[0x1]; - u_char cl_livr; /* 0x09 */ - u_char anon3[0x6]; - u_char cl_cor1; /* 0x10 */ - u_char cl_ier; /* 0x11 */ - u_char cl_stcr; /* 0x12 */ - u_char cl_ccr; /* 0x13 */ - u_char cl_cor5; /* 0x14 */ - u_char cl_cor4; /* 0x15 */ - u_char cl_cor3; /* 0x16 */ - u_char cl_cor2; /* 0x17 */ - u_char cl_cor6; /* 0x18 */ - u_char cl_dmabsts; /* 0x19 */ - u_char cl_csr; /* 0x1a */ - u_char cl_cmr; /* 0x1b */ - u_char cl_schr4; /* 0x1c */ - u_char cl_schr3; /* 0x1d */ - u_char cl_schr2; /* 0x1e */ - u_char cl_schr1; /* 0x1f */ - u_char anon5[0x2]; - u_char cl_scrh; /* 0x22 */ - u_char cl_scrl; /* 0x23 */ + volatile u_char anon1[0x7]; + volatile u_char cl_cor7; /* 0x07 */ + volatile u_char anon2[0x1]; + volatile u_char cl_livr; /* 0x09 */ + volatile u_char anon3[0x6]; + volatile u_char cl_cor1; /* 0x10 */ + volatile u_char cl_ier; /* 0x11 */ + volatile u_char cl_stcr; /* 0x12 */ + volatile u_char cl_ccr; /* 0x13 */ + volatile u_char cl_cor5; /* 0x14 */ + volatile u_char cl_cor4; /* 0x15 */ + volatile u_char cl_cor3; /* 0x16 */ + volatile u_char cl_cor2; /* 0x17 */ + volatile u_char cl_cor6; /* 0x18 */ + volatile u_char cl_dmabsts; /* 0x19 */ + volatile u_char cl_csr; /* 0x1a */ + volatile u_char cl_cmr; /* 0x1b */ + volatile u_char cl_schr4; /* 0x1c */ + volatile u_char cl_schr3; /* 0x1d */ + volatile u_char cl_schr2; /* 0x1e */ + volatile u_char cl_schr1; /* 0x1f */ + volatile u_char anon5[0x2]; + volatile u_char cl_scrh; /* 0x22 */ + volatile u_char cl_scrl; /* 0x23 */ #define cl_rtpr rtpr.rtpr_rtpr #define cl_rtprh rtpr.hl.rtpr_rtprh #define cl_rtprl rtpr.hl.rtpr_rtprl union { - u_short rtpr_rtpr; /* 0x24 */ + volatile u_short rtpr_rtpr; /* 0x24 */ struct { - u_char rtpr_rtprh; /* 0x24 */ - u_char rtpr_rtprl; /* 0x25 */ + volatile u_char rtpr_rtprh; /* 0x24 */ + volatile u_char rtpr_rtprl; /* 0x25 */ } hl; } rtpr; - u_char cl_licr; /* 0x26 */ - u_char anon6[0x7]; - u_char cl_lnxt; /* 0x2e */ - u_char anon7[0x1]; - u_char cl_rfoc; /* 0x30 */ - u_char anon8[0x7]; - u_char cl_rtbadru; /* 0x38 */ - u_char anon9[0x1]; - u_char cl_rtbadrl; /* 0x3a */ - u_char anona[0x1]; - u_char cl_rcbadru; /* 0x3c */ - u_char anonb[0x1]; - u_char cl_rcbadrl; /* 0x3e */ - u_char anonc[0x1]; - u_char cl_arbadru; /* 0x40 */ - u_char anond[0x1]; - u_char cl_arbadrl; /* 0x42 */ - u_char anone[0x1]; - u_char cl_brbadru; /* 0x44 */ - u_char anonf[0x1]; - u_char cl_brbadrl; /* 0x46 */ - u_char anong[0x1]; - u_char cl_brbcnt; /* 0x48 */ - u_char anonh[0x1]; - u_char cl_arbcnt; /* 0x4a */ - u_char anoni[0x3]; - u_char cl_brbsts; /* 0x4e */ - u_char cl_arbsts; /* 0x4f */ - u_char cl_atbadru; /* 0x50 */ - u_char anonj[0x1]; - u_char cl_atbadrl; /* 0x52 */ - u_char anonk[0x1]; - u_char cl_btbadru; /* 0x54 */ - u_char anonl[0x1]; - u_char cl_btbadrl; /* 0x56 */ - u_char anonm[0x1]; - u_char cl_btbcnt; /* 0x58 */ - u_char anonn[0x1]; - u_char cl_atbcnt; /* 0x5a */ - u_char anono[0x3]; - u_char cl_btbsts; /* 0x5e */ - u_char cl_atbsts; /* 0x5f */ - u_char anonp[0x20]; - u_char cl_tftc; /* 0x80 */ - u_char cl_gfrcr; /* 0x81 */ - u_char anonq[0x2]; - u_char cl_reoir; /* 0x84 */ - u_char cl_teoir; /* 0x85 */ - u_char cl_meoir; /* 0x86 */ - u_char anonr[0x1]; + volatile u_char cl_licr; /* 0x26 */ + volatile u_char anon6[0x7]; + volatile u_char cl_lnxt; /* 0x2e */ + volatile u_char anon7[0x1]; + volatile u_char cl_rfoc; /* 0x30 */ + volatile u_char anon8[0x7]; + volatile u_short cl_tcbadru; /* 0x38 */ + volatile u_short cl_tcbadrl; /* 0x3a */ + volatile u_short cl_rcbadru; /* 0x3c */ + volatile u_short cl_rcbadrl; /* 0x3e */ + volatile u_short cl_arbadru; /* 0x40 */ + volatile u_short cl_arbadrl; /* 0x42 */ + volatile u_short cl_brbadru; /* 0x44 */ + volatile u_short cl_brbadrl; /* 0x46 */ + volatile u_short cl_brbcnt; /* 0x48 */ + volatile u_short cl_arbcnt; /* 0x4a */ + volatile u_char anoni[0x2]; + volatile u_char cl_brbsts; /* 0x4e */ + volatile u_char cl_arbsts; /* 0x4f */ +#define cl_atbadr atbadr.atbadr +#define cl_atbadru atbadr.hl.atbadru +#define cl_atbadrl atbadr.hl.atbadrl + union { + struct { + volatile u_short atbadru; /* 0x50 */ + volatile u_short atbadrl; /* 0x52 */ + } hl; + volatile u_long atbadr; /* 0x50 */ + } atbadr; +#define cl_btbadr btbadr.btbadr +#define cl_btbadru btbadr.hl.btbadru +#define cl_btbadrl btbadr.hl.btbadrl + union { + struct { + volatile u_short btbadru; /* 0x54 */ + volatile u_short btbadrl; /* 0x56 */ + } hl; + volatile u_long btbadr; /* 0x54 */ + } btbadr; + volatile u_short cl_btbcnt; /* 0x58 */ + volatile u_short cl_atbcnt; /* 0x5a */ + volatile u_char anono[0x2]; + volatile u_char cl_btbsts; /* 0x5e */ + volatile u_char cl_atbsts; /* 0x5f */ + volatile u_char anonp[0x20]; + volatile u_char cl_tftc; /* 0x80 */ + volatile u_char cl_gfrcr; /* 0x81 */ + volatile u_char anonq[0x2]; + volatile u_char cl_reoir; /* 0x84 */ + volatile u_char cl_teoir; /* 0x85 */ + volatile u_char cl_meoir; /* 0x86 */ + volatile u_char anonr[0x1]; #define cl_risr risr.risr_risr #define cl_risrl risr.hl.risr_risrl #define cl_risrh risr.hl.risr_risrh union { - u_short risr_risr; /* 0x88 */ + volatile u_short risr_risr; /* 0x88 */ struct { - u_char risr_risrh; /* 0x88 */ - u_char risr_risrl; /* 0x89 */ + volatile u_char risr_risrh; /* 0x88 */ + volatile u_char risr_risrl; /* 0x89 */ } hl; } risr; - u_char cl_tisr; /* 0x8a */ - u_char cl_misr; /* 0x8b */ - u_char anons[0x2]; - u_char cl_bercnt; /* 0x8e */ - u_char anont[0x31]; - u_char cl_tcor; /* 0xc0 */ - u_char anonu[0x2]; - u_char cl_tbpr; /* 0xc3 */ - u_char anonv[0x4]; - u_char cl_rcor; /* 0xc8 */ - u_char anonw[0x2]; - u_char cl_rbpr; /* 0xcb */ - u_char anonx[0xa]; - u_char cl_cpsr; /* 0xd6 */ - u_char anony[0x3]; - u_char cl_tpr; /* 0xda */ - u_char anonz[0x3]; - u_char cl_msvr_rts; /* 0xde */ - u_char cl_msvr_dtr; /* 0xdf */ - u_char cl_tpilr; /* 0xe0 */ - u_char cl_rpilr; /* 0xe1 */ - u_char cl_stk; /* 0xe2 */ - u_char cl_mpilr; /* 0xe3 */ - u_char anonA[0x8]; - u_char cl_tir; /* 0xec */ - u_char cl_rir; /* 0xed */ - u_char cl_car; /* 0xee */ - u_char cl_mir; /* 0xef */ - u_char anonB[0x6]; - u_char cl_dmr; /* 0xf6 */ - u_char anonC[0x1]; + volatile u_char cl_tisr; /* 0x8a */ + volatile u_char cl_misr; /* 0x8b */ + volatile u_char anons[0x2]; + volatile u_char cl_bercnt; /* 0x8e */ + volatile u_char anont[0x31]; + volatile u_char cl_tcor; /* 0xc0 */ + volatile u_char anonu[0x2]; + volatile u_char cl_tbpr; /* 0xc3 */ + volatile u_char anonv[0x4]; + volatile u_char cl_rcor; /* 0xc8 */ + volatile u_char anonw[0x2]; + volatile u_char cl_rbpr; /* 0xcb */ + volatile u_char anonx[0xa]; + volatile u_char cl_cpsr; /* 0xd6 */ + volatile u_char anony[0x3]; + volatile u_char cl_tpr; /* 0xda */ + volatile u_char anonz[0x3]; + volatile u_char cl_msvr_rts; /* 0xde */ + volatile u_char cl_msvr_dtr; /* 0xdf */ + volatile u_char cl_tpilr; /* 0xe0 */ + volatile u_char cl_rpilr; /* 0xe1 */ + volatile u_char cl_stk; /* 0xe2 */ + volatile u_char cl_mpilr; /* 0xe3 */ + volatile u_char anonA[0x8]; + volatile u_char cl_tir; /* 0xec */ + volatile u_char cl_rir; /* 0xed */ + volatile u_char cl_car; /* 0xee */ + volatile u_char cl_mir; /* 0xef */ + volatile u_char anonB[0x6]; + volatile u_char cl_dmr; /* 0xf6 */ + volatile u_char anonC[0x1]; #define cl_rdr cl_tdr - u_char cl_tdr; /* 0xf8 */ - u_char anonD[7]; -}; /* 0x200 total */ + volatile u_char cl_tdr; /* 0xf8 */ + volatile u_char anonD[7]; +}; |