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