summaryrefslogtreecommitdiff
path: root/sys/arch/mvme68k/dev
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-12-01 18:13:17 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-12-01 18:13:17 +0000
commitba2671a1203ff5f02f59aae6a0bfee14ef071085 (patch)
treea2bd476a4d48e793bc783a77840baf76740ba6a0 /sys/arch/mvme68k/dev
parent7962a199da906f0ef3973d6ea8f9762c4e47105d (diff)
fixed ddb, improved fifo handling, new still-not-working dma support
from drahn@pacific.urbana.mcd.mot.com
Diffstat (limited to 'sys/arch/mvme68k/dev')
-rw-r--r--sys/arch/mvme68k/dev/cl.c481
-rw-r--r--sys/arch/mvme68k/dev/clreg.h238
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];
+};