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