Annotation of sys/arch/mvme88k/dev/dart.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: dart.c,v 1.49 2007/05/19 20:35:20 miod Exp $ */
2:
3: /*
4: * Mach Operating System
5: * Copyright (c) 1993-1991 Carnegie Mellon University
6: * All Rights Reserved.
7: *
8: * Permission to use, copy, modify and distribute this software and its
9: * documentation is hereby granted, provided that both the copyright
10: * notice and this permission notice appear in all copies of the
11: * software, derivative works or modified versions, and any portions
12: * thereof, and that both notices appear in supporting documentation.
13: *
14: * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15: * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
16: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17: *
18: * Carnegie Mellon requests users of this software to return to
19: *
20: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21: * School of Computer Science
22: * Carnegie Mellon University
23: * Pittsburgh PA 15213-3890
24: *
25: * any improvements or extensions that they make and grant Carnegie the
26: * rights to redistribute these changes.
27: */
28:
29: #include <sys/param.h>
30: #include <sys/ioctl.h>
31: #include <sys/proc.h>
32: #include <sys/tty.h>
33: #include <sys/systm.h>
34: #include <sys/device.h>
35:
36: #include <machine/autoconf.h>
37: #include <machine/conf.h>
38: #include <machine/cpu.h>
39:
40: #include <dev/cons.h>
41:
42: #include <machine/mvme188.h>
43: #include <mvme88k/dev/sysconreg.h>
44: #include <mvme88k/dev/dartreg.h>
45:
46: #ifdef DDB
47: #include <ddb/db_var.h>
48: #endif
49:
50: #define NDARTPORTS 2 /* Number of ports */
51:
52: struct dart_info {
53: struct tty *tty;
54: u_char dart_swflags;
55: };
56:
57: /* saved registers */
58: struct dart_sv_reg {
59: u_int8_t sv_mr1[NDARTPORTS];
60: u_int8_t sv_mr2[NDARTPORTS];
61: u_int8_t sv_csr[NDARTPORTS];
62: u_int8_t sv_cr[NDARTPORTS];
63: u_int8_t sv_imr;
64: };
65:
66: struct dartsoftc {
67: struct device sc_dev;
68: bus_space_tag_t sc_iot;
69: bus_space_handle_t sc_ioh;
70: struct intrhand sc_ih;
71:
72: struct dart_sv_reg sc_sv_reg;
73: struct dart_info sc_dart[NDARTPORTS];
74: };
75:
76: int dartmatch(struct device *parent, void *self, void *aux);
77: void dartattach(struct device *parent, struct device *self, void *aux);
78:
79: struct cfattach dart_ca = {
80: sizeof(struct dartsoftc), dartmatch, dartattach
81: };
82:
83: struct cfdriver dart_cd = {
84: NULL, "dart", DV_TTY
85: };
86:
87: /* console is on the first port */
88: #define CONS_PORT A_PORT
89:
90: /* prototypes */
91: cons_decl(dart);
92: int dart_speed(int);
93: struct tty *darttty(dev_t);
94: void dartstart(struct tty *);
95: int dartmctl(dev_t, int, int);
96: int dartparam(struct tty *, struct termios *);
97: void dartmodemtrans(struct dartsoftc *, unsigned int, unsigned int);
98: void dartrint(struct dartsoftc *, int);
99: void dartxint(struct dartsoftc *, int);
100: int dartintr(void *);
101:
102: /*
103: * DUART registers are mapped as the least-significant byte of 32-bit
104: * addresses. The following macros hide this.
105: */
106:
107: #define DART_SIZE 0x40
108: #define dart_read(sc, reg) \
109: bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, 3 + ((reg) << 2))
110: #define dart_write(sc, reg, val) \
111: bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, 3 + ((reg) << 2), (val))
112:
113: #define DART_PORT(dev) minor(dev)
114:
115: int
116: dartmatch(struct device *parent, void *cf, void *aux)
117: {
118: struct confargs *ca = aux;
119: bus_space_handle_t ioh;
120: int rc;
121:
122: if (brdtyp != BRD_188)
123: return (0);
124:
125: /*
126: * We do not accept empty locators here...
127: */
128: if (ca->ca_paddr != DART_BASE)
129: return (0);
130:
131: if (bus_space_map(ca->ca_iot, ca->ca_paddr, DART_SIZE, 0, &ioh) != 0)
132: return (0);
133: rc = badaddr((vaddr_t)bus_space_vaddr(ca->ca_iot, ioh), 4);
134: bus_space_unmap(ca->ca_iot, ca->ca_paddr, DART_SIZE);
135:
136: return (rc == 0);
137: }
138:
139: void
140: dartattach(struct device *parent, struct device *self, void *aux)
141: {
142: struct dartsoftc *sc = (struct dartsoftc *)self;
143: struct confargs *ca = aux;
144: bus_space_handle_t ioh;
145:
146: if (ca->ca_ipl < 0)
147: ca->ca_ipl = IPL_TTY;
148:
149: sc->sc_iot = ca->ca_iot;
150: if (bus_space_map(sc->sc_iot, ca->ca_paddr, DART_SIZE, 0, &ioh) != 0) {
151: printf(": can't map registers!\n");
152: return;
153: }
154: sc->sc_ioh = ioh;
155:
156: /* save standard initialization */
157: sc->sc_sv_reg.sv_mr1[A_PORT] = PARDIS | RXRTS | CL8;
158: sc->sc_sv_reg.sv_mr2[A_PORT] = /* TXCTS | */ SB1;
159: sc->sc_sv_reg.sv_csr[A_PORT] = BD9600;
160: sc->sc_sv_reg.sv_cr[A_PORT] = TXEN | RXEN;
161:
162: sc->sc_sv_reg.sv_mr1[B_PORT] = PARDIS | RXRTS | CL8;
163: sc->sc_sv_reg.sv_mr2[B_PORT] = /* TXCTS | */ SB1;
164: sc->sc_sv_reg.sv_csr[B_PORT] = BD9600;
165: sc->sc_sv_reg.sv_cr[B_PORT] = TXEN | RXEN;
166:
167: /* Start out with Tx and RX interrupts disabled */
168: /* Enable input port change interrupt */
169: sc->sc_sv_reg.sv_imr = IIPCHG;
170:
171: /*
172: * Although we are still running using the BUG routines,
173: * this device will be elected as the console after
174: * autoconf.
175: * We do not even test since we know we are an MVME188 and
176: * console is always on the first port.
177: */
178: printf(": console");
179:
180: /* reset port a */
181: dart_write(sc, DART_CRA, RXRESET | TXDIS | RXDIS);
182: DELAY_CR;
183: dart_write(sc, DART_CRA, TXRESET | TXDIS | RXDIS);
184: DELAY_CR;
185: dart_write(sc, DART_CRA, ERRRESET | TXDIS | RXDIS);
186: DELAY_CR;
187: dart_write(sc, DART_CRA, BRKINTRESET | TXDIS | RXDIS);
188: DELAY_CR;
189: dart_write(sc, DART_CRA, MRRESET | TXDIS | RXDIS);
190: DELAY_CR;
191:
192: /* reset port b */
193: dart_write(sc, DART_CRB, RXRESET | TXDIS | RXDIS);
194: DELAY_CR;
195: dart_write(sc, DART_CRB, TXRESET | TXDIS | RXDIS);
196: DELAY_CR;
197: dart_write(sc, DART_CRB, ERRRESET | TXDIS | RXDIS);
198: DELAY_CR;
199: dart_write(sc, DART_CRB, BRKINTRESET | TXDIS | RXDIS);
200: DELAY_CR;
201: dart_write(sc, DART_CRB, MRRESET | TXDIS | RXDIS);
202: DELAY_CR;
203:
204: /* initialize ports */
205: dart_write(sc, DART_MR1A, sc->sc_sv_reg.sv_mr1[A_PORT]);
206: dart_write(sc, DART_MR2A, sc->sc_sv_reg.sv_mr2[A_PORT]);
207: dart_write(sc, DART_CSRA, sc->sc_sv_reg.sv_csr[A_PORT]);
208: dart_write(sc, DART_CRA, sc->sc_sv_reg.sv_cr[A_PORT]);
209:
210: dart_write(sc, DART_MR1B, sc->sc_sv_reg.sv_mr1[B_PORT]);
211: dart_write(sc, DART_MR2B, sc->sc_sv_reg.sv_mr2[B_PORT]);
212: dart_write(sc, DART_CSRB, sc->sc_sv_reg.sv_csr[B_PORT]);
213: dart_write(sc, DART_CRB, sc->sc_sv_reg.sv_cr[B_PORT]);
214:
215: /* initialize common register of a DUART */
216: dart_write(sc, DART_OPRS, OPDTRA | OPRTSA | OPDTRB | OPRTSB);
217:
218: dart_write(sc, DART_CTUR, SLCTIM >> 8);
219: dart_write(sc, DART_CTLR, SLCTIM & 0xff);
220: dart_write(sc, DART_ACR, BDSET2 | CCLK16 | IPDCDIB | IPDCDIA);
221: dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
222: dart_write(sc, DART_OPCR, OPSET);
223: dart_write(sc, DART_IVR, SYSCON_VECT + SYSCV_SCC);
224:
225: /* enable interrupts */
226: sc->sc_ih.ih_fn = dartintr;
227: sc->sc_ih.ih_arg = sc;
228: sc->sc_ih.ih_wantframe = 0;
229: sc->sc_ih.ih_ipl = ca->ca_ipl;
230:
231: sysconintr_establish(SYSCV_SCC, &sc->sc_ih, self->dv_xname);
232: printf("\n");
233: }
234:
235: /* speed tables */
236: const struct dart_s {
237: int kspeed;
238: int dspeed;
239: } dart_speeds[] = {
240: { B0, 0 }, /* 0 baud, special HUP condition */
241: { B50, NOBAUD }, /* 50 baud, not implemented */
242: { B75, BD75 }, /* 75 baud */
243: { B110, BD110 }, /* 110 baud */
244: { B134, BD134 }, /* 134.5 baud */
245: { B150, BD150 }, /* 150 baud */
246: { B200, NOBAUD }, /* 200 baud, not implemented */
247: { B300, BD300 }, /* 300 baud */
248: { B600, BD600 }, /* 600 baud */
249: { B1200, BD1200 }, /* 1200 baud */
250: { B1800, BD1800 }, /* 1800 baud */
251: { B2400, BD2400 }, /* 2400 baud */
252: { B4800, BD4800 }, /* 4800 baud */
253: { B9600, BD9600 }, /* 9600 baud */
254: { B19200, BD19200 }, /* 19200 baud */
255: { -1, NOBAUD }, /* anything more is uncivilized */
256: };
257:
258: int
259: dart_speed(int speed)
260: {
261: const struct dart_s *ds;
262:
263: for (ds = dart_speeds; ds->kspeed != -1; ds++)
264: if (ds->kspeed == speed)
265: return ds->dspeed;
266:
267: return NOBAUD;
268: }
269:
270: struct tty *
271: darttty(dev_t dev)
272: {
273: unsigned int port;
274: struct dartsoftc *sc;
275:
276: port = DART_PORT(dev);
277: if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS)
278: return (NULL);
279:
280: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
281: return sc->sc_dart[port].tty;
282: }
283:
284: void
285: dartstart(struct tty *tp)
286: {
287: struct dartsoftc *sc;
288: dev_t dev;
289: int s;
290: int port, tries;
291: int c;
292: bus_addr_t ptaddr;
293:
294: dev = tp->t_dev;
295: port = DART_PORT(dev);
296: if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS)
297: return;
298:
299: if ((tp->t_state & TS_ISOPEN) == 0)
300: return;
301:
302: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
303: ptaddr = port ? DART_B_BASE : DART_A_BASE;
304:
305: s = spltty();
306:
307: if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
308: goto bail;
309:
310: if (tp->t_outq.c_cc <= tp->t_lowat) {
311: if (tp->t_state & TS_ASLEEP) {
312: tp->t_state &= ~TS_ASLEEP;
313: wakeup((caddr_t)&tp->t_outq);
314: }
315: selwakeup(&tp->t_wsel);
316: if (tp->t_outq.c_cc == 0)
317: goto bail;
318: }
319:
320: tp->t_state |= TS_BUSY;
321: while (tp->t_outq.c_cc != 0) {
322:
323: /* load transmitter until it is full */
324: for (tries = 10000; tries != 0; tries --)
325: if (dart_read(sc, ptaddr + DART_SRA) & TXRDY)
326: break;
327:
328: if (tries == 0) {
329: timeout_add(&tp->t_rstrt_to, 1);
330: tp->t_state |= TS_TIMEOUT;
331: break;
332: } else {
333: c = getc(&tp->t_outq);
334:
335: dart_write(sc, ptaddr + DART_TBA, c & 0xff);
336:
337: if (port == A_PORT)
338: sc->sc_sv_reg.sv_imr |= ITXRDYA;
339: else
340: sc->sc_sv_reg.sv_imr |= ITXRDYB;
341: dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
342: }
343: }
344: tp->t_state &= ~TS_BUSY;
345:
346: bail:
347: splx(s);
348: }
349:
350: int
351: dartstop(struct tty *tp, int flag)
352: {
353: int s;
354:
355: s = spltty();
356: if (tp->t_state & TS_BUSY) {
357: if ((tp->t_state & TS_TTSTOP) == 0)
358: tp->t_state |= TS_FLUSH;
359: }
360: splx(s);
361:
362: return 0;
363: }
364:
365: #define HANDLE_FLAG(_FLAG_, _PORT_, _AFLAG_, _BFLAG_) \
366: do { \
367: if (flags & (_FLAG_)) { \
368: newflags |= ((_PORT_) == A_PORT) ? (_AFLAG_) : (_BFLAG_); \
369: flags &= ~(_FLAG_); \
370: } \
371: } while (0)
372:
373: /*
374: * To be called at spltty - tty already locked.
375: * Returns status of carrier.
376: */
377:
378: int
379: dartmctl(dev_t dev, int flags, int how)
380: {
381: struct dartsoftc *sc;
382: int port;
383: int newflags = 0;
384: struct dart_info *dart;
385: int s;
386:
387: port = DART_PORT(dev);
388: if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS)
389: return (ENODEV);
390:
391: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
392: dart = &sc->sc_dart[port];
393:
394: s = spltty();
395:
396: HANDLE_FLAG(TIOCM_DTR, port, OPDTRA, OPDTRB);
397: HANDLE_FLAG(TIOCM_RTS, port, OPRTSA, OPRTSB);
398:
399: switch (how) {
400: case DMSET:
401: dart_write(sc, DART_OPRS, newflags);
402: dart_write(sc, DART_OPRR, ~newflags);
403: break;
404: case DMBIS:
405: dart_write(sc, DART_OPRS, newflags);
406: break;
407: case DMBIC:
408: dart_write(sc, DART_OPRR, newflags);
409: break;
410: case DMGET:
411: flags = 0; /* XXX not supported */
412: break;
413: }
414:
415: splx(s);
416: return (flags);
417: }
418:
419: int
420: dartioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
421: {
422: int error;
423: int port;
424: struct tty *tp;
425: struct dart_info *dart;
426: struct dartsoftc *sc;
427:
428: port = DART_PORT(dev);
429: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
430: dart = &sc->sc_dart[port];
431:
432: tp = dart->tty;
433: if (tp == NULL)
434: return (ENXIO);
435:
436: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
437: if (error >= 0)
438: return(error);
439:
440: error = ttioctl(tp, cmd, data, flag, p);
441: if (error >= 0)
442: return(error);
443:
444: switch (cmd) {
445: case TIOCSBRK:
446: case TIOCCBRK:
447: break;
448: case TIOCSDTR:
449: (void)dartmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
450: break;
451: case TIOCCDTR:
452: (void)dartmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
453: break;
454: case TIOCMSET:
455: (void)dartmctl(dev, *(int *) data, DMSET);
456: break;
457: case TIOCMBIS:
458: (void)dartmctl(dev, *(int *) data, DMBIS);
459: break;
460: case TIOCMBIC:
461: (void)dartmctl(dev, *(int *) data, DMBIC);
462: break;
463: case TIOCMGET:
464: *(int *)data = dartmctl(dev, 0, DMGET);
465: break;
466: case TIOCGFLAGS:
467: if (CONS_PORT == port)
468: dart->dart_swflags |= TIOCFLAG_SOFTCAR;
469: *(int *)data = dart->dart_swflags;
470: break;
471: case TIOCSFLAGS:
472: error = suser(p, 0);
473: if (error != 0)
474: return (EPERM);
475:
476: dart->dart_swflags = *(int *)data;
477: if (CONS_PORT == port)
478: dart->dart_swflags |= TIOCFLAG_SOFTCAR;
479: dart->dart_swflags &= /* only allow valid flags */
480: (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
481: break;
482: default:
483: return (ENOTTY);
484: }
485:
486: return (0);
487: }
488:
489: int
490: dartparam(struct tty *tp, struct termios *t)
491: {
492: int flags;
493: int port;
494: int speeds;
495: unsigned char mr1, mr2;
496: struct dart_info *dart;
497: struct dartsoftc *sc;
498: dev_t dev;
499: bus_addr_t ptaddr;
500:
501: dev = tp->t_dev;
502: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
503: port = DART_PORT(dev);
504: dart = &sc->sc_dart[port];
505: ptaddr = port ? DART_B_BASE : DART_A_BASE;
506:
507: tp->t_ispeed = t->c_ispeed;
508: tp->t_ospeed = t->c_ospeed;
509: tp->t_cflag = t->c_cflag;
510:
511: flags = tp->t_flags;
512:
513: /* Reset to make global changes*/
514: /* disable Tx and Rx */
515:
516: if (CONS_PORT != port) {
517: if (port == A_PORT)
518: sc->sc_sv_reg.sv_imr &= ~(ITXRDYA | IRXRDYA);
519: else
520: sc->sc_sv_reg.sv_imr &= ~(ITXRDYB | IRXRDYB);
521: dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
522:
523: /* hang up on zero baud rate */
524: if (tp->t_ispeed == 0) {
525: dartmctl(dev, HUPCL, DMSET);
526: return (0);
527: } else {
528: /* set baudrate */
529: speeds = dart_speed(tp->t_ispeed);
530: if (speeds == NOBAUD)
531: speeds = sc->sc_sv_reg.sv_csr[port];
532: dart_write(sc, ptaddr + DART_CSRA, speeds);
533: sc->sc_sv_reg.sv_csr[port] = speeds;
534: }
535:
536: /* get saved mode registers and clear set up parameters */
537: mr1 = sc->sc_sv_reg.sv_mr1[port];
538: mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK);
539:
540: mr2 = sc->sc_sv_reg.sv_mr2[port];
541: mr2 &= ~SBMASK;
542:
543: /* set up character size */
544: if (flags & CS8)
545: mr1 |= CL8;
546: else if (tp->t_ispeed == B134)
547: mr1 |= CL6;
548: else
549: mr1 |= CL7;
550:
551: /* set up stop bits */
552: if (tp->t_ospeed == B110)
553: mr2 |= SB2;
554: else
555: mr2 |= SB1;
556:
557: /* set up parity */
558: if (((flags & PARENB) != PARENB) &&
559: (flags & PARENB)) {
560: mr1 |= PAREN;
561: if (flags & PARODD)
562: mr1 |= ODDPAR;
563: else
564: mr1 |= EVENPAR;
565: } else
566: mr1 |= PARDIS;
567:
568: if (sc->sc_sv_reg.sv_mr1[port] != mr1 ||
569: sc->sc_sv_reg.sv_mr2[port] != mr2) {
570: /* write mode registers to duart */
571: dart_write(sc, ptaddr + DART_CRA, MRRESET);
572: dart_write(sc, ptaddr + DART_MR1A, mr1);
573: dart_write(sc, ptaddr + DART_MR2A, mr2);
574:
575: /* save changed mode registers */
576: sc->sc_sv_reg.sv_mr1[port] = mr1;
577: sc->sc_sv_reg.sv_mr2[port] = mr2;
578: }
579: }
580:
581: /* enable transmitter? */
582: if (tp->t_state & TS_BUSY) {
583: if (port == A_PORT)
584: sc->sc_sv_reg.sv_imr |= ITXRDYA;
585: else
586: sc->sc_sv_reg.sv_imr |= ITXRDYB;
587: dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
588: }
589:
590: /* re-enable the receiver */
591: DELAY_CR;
592: if (port == A_PORT)
593: sc->sc_sv_reg.sv_imr |= IRXRDYA;
594: else
595: sc->sc_sv_reg.sv_imr |= IRXRDYB;
596: dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
597:
598: return (0);
599: }
600:
601: void
602: dartmodemtrans(struct dartsoftc *sc, unsigned int ip, unsigned int ipcr)
603: {
604: unsigned int dcdstate;
605: struct tty *tp;
606: int port;
607: struct dart_info *dart;
608:
609: /* input is inverted at port!!! */
610: if (ipcr & IPCRDCDA) {
611: port = A_PORT;
612: dcdstate = !(ip & IPDCDA);
613: } else if (ipcr & IPCRDCDB) {
614: port = B_PORT;
615: dcdstate = !(ip & IPDCDB);
616: } else {
617: printf("dartmodemtrans: unknown transition ip=0x%x ipcr=0x%x\n",
618: ip, ipcr);
619: return;
620: }
621:
622: dart = &sc->sc_dart[port];
623: tp = dart->tty;
624: if (tp != NULL)
625: ttymodem(tp, dcdstate);
626: }
627:
628: int
629: dartopen(dev_t dev, int flag, int mode, struct proc *p)
630: {
631: int s, port;
632: struct dart_info *dart;
633: struct dartsoftc *sc;
634: struct tty *tp;
635:
636: port = DART_PORT(dev);
637: if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS)
638: return (ENODEV);
639: sc = (struct dartsoftc *)dart_cd.cd_devs[0]; /* the only one */
640: dart = &sc->sc_dart[port];
641:
642: s = spltty();
643: if (dart->tty != NULL)
644: tp = dart->tty;
645: else
646: tp = dart->tty = ttymalloc();
647:
648: tp->t_oproc = dartstart;
649: tp->t_param = dartparam;
650: tp->t_dev = dev;
651:
652: if ((tp->t_state & TS_ISOPEN) == 0) {
653: ttychars(tp);
654: tp->t_iflag = TTYDEF_IFLAG;
655: tp->t_oflag = TTYDEF_OFLAG;
656: tp->t_lflag = TTYDEF_LFLAG;
657: tp->t_ispeed = tp->t_ospeed = B9600;
658: dartparam(tp, &tp->t_termios);
659: if (port == CONS_PORT) {
660: /* console is 8N1 */
661: tp->t_cflag = (CREAD | CS8 | HUPCL);
662: } else {
663: tp->t_cflag = TTYDEF_CFLAG;
664: }
665: ttsetwater(tp);
666: (void)dartmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
667: tp->t_state |= TS_CARR_ON;
668: } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
669: splx(s);
670: return (EBUSY);
671: }
672:
673: /*
674: * Reset the tty pointer, as there could have been a dialout
675: * use of the tty with a dialin open waiting.
676: */
677: tp->t_dev = dev;
678: splx(s);
679: return ((*linesw[tp->t_line].l_open)(dev, tp));
680: }
681:
682: int
683: dartclose(dev_t dev, int flag, int mode, struct proc *p)
684: {
685: struct tty *tp;
686: struct dart_info *dart;
687: struct dartsoftc *sc;
688: int port;
689:
690: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
691: port = DART_PORT(dev);
692: dart = &sc->sc_dart[port];
693:
694: tp = dart->tty;
695: (*linesw[tp->t_line].l_close)(tp, flag);
696: ttyclose(tp);
697:
698: return (0);
699: }
700:
701: int
702: dartread(dev_t dev, struct uio *uio, int flag)
703: {
704: int port;
705: struct tty *tp;
706: struct dart_info *dart;
707: struct dartsoftc *sc;
708:
709: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
710: port = DART_PORT(dev);
711: dart = &sc->sc_dart[port];
712:
713: tp = dart->tty;
714: if (tp == NULL)
715: return (ENXIO);
716: return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
717: }
718:
719: int
720: dartwrite(dev_t dev, struct uio *uio, int flag)
721: {
722: int port;
723: struct tty *tp;
724: struct dart_info *dart;
725: struct dartsoftc *sc;
726:
727: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
728: port = DART_PORT(dev);
729: dart = &sc->sc_dart[port];
730:
731: tp = dart->tty;
732: if (tp == NULL)
733: return (ENXIO);
734: return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
735: }
736:
737: void
738: dartrint(struct dartsoftc *sc, int port)
739: {
740: struct tty *tp;
741: unsigned char data, sr;
742: struct dart_info *dart;
743: bus_addr_t ptaddr;
744:
745: dart = &sc->sc_dart[port];
746: ptaddr = port ? DART_B_BASE : DART_A_BASE;
747: tp = dart->tty;
748:
749: /* read status reg */
750: while ((sr = dart_read(sc, ptaddr + DART_SRA)) & RXRDY) {
751: /* read data and reset receiver */
752: data = dart_read(sc, ptaddr + DART_RBA);
753:
754: if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0 &&
755: CONS_PORT != port) {
756: return;
757: }
758:
759: if (sr & RBRK) {
760: /* clear break state */
761: dart_write(sc, ptaddr + DART_CRA, BRKINTRESET);
762: DELAY_CR;
763: dart_write(sc, ptaddr + DART_CRA, ERRRESET);
764:
765: #if defined(DDB)
766: if (db_console != 0 && port == CONS_PORT)
767: Debugger();
768: #endif
769: } else {
770: if (sr & (FRERR|PERR|ROVRN)) { /* errors */
771: if (sr & ROVRN)
772: printf("%s: receiver overrun port %c\n",
773: sc->sc_dev.dv_xname, 'A' + port);
774: if (sr & FRERR)
775: printf("%s: framing error port %c\n",
776: sc->sc_dev.dv_xname, 'A' + port);
777: if (sr & PERR)
778: printf("%s: parity error port %c\n",
779: sc->sc_dev.dv_xname, 'A' + port);
780: /* clear error state */
781: dart_write(sc, ptaddr + DART_CRA, ERRRESET);
782: } else {
783: /* no errors */
784: (*linesw[tp->t_line].l_rint)(data,tp);
785: #if 0
786: {
787: if (tp->t_ispeed == B134) /* CS6 */
788: data &= 077;
789: else if (tp->t_flags & CS8)
790: ;
791: else
792: data &= 0177; /* CS7 */
793: ttyinput(data, tp);
794: }
795: #endif
796: }
797: }
798: }
799: }
800:
801: void
802: dartxint(struct dartsoftc *sc, int port)
803: {
804: struct tty *tp;
805: struct dart_info *dart;
806:
807: dart = &sc->sc_dart[port];
808: tp = dart->tty;
809:
810: if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0)
811: goto out;
812:
813: if (tp->t_state & TS_FLUSH)
814: tp->t_state &= ~TS_FLUSH;
815:
816: if (tp->t_state & TS_BUSY) {
817: tp->t_state &= ~TS_BUSY;
818: dartstart(tp);
819: if (tp->t_state & TS_BUSY) {
820: return;
821: }
822: }
823: out:
824:
825: /* disable transmitter */
826: if (port == 0)
827: sc->sc_sv_reg.sv_imr &= ~ITXRDYA;
828: else
829: sc->sc_sv_reg.sv_imr &= ~ITXRDYB;
830:
831: dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
832: }
833:
834: int
835: dartintr(void *arg)
836: {
837: struct dartsoftc *sc = arg;
838: unsigned char isr, imr;
839: int port;
840:
841: /* read interrupt status register and mask with imr */
842: isr = dart_read(sc, DART_ISR);
843: imr = sc->sc_sv_reg.sv_imr;
844:
845: if ((isr & imr) == 0) {
846: /*
847: * We got an interrupt on a disabled condition (such as TX
848: * ready change on a disabled port). This should not happen,
849: * but we have to claim the interrupt anyway.
850: */
851: #if defined(DIAGNOSTIC) && !defined(MULTIPROCESSOR)
852: printf("dartintr: spurious interrupt, isr %x imr %x\n",
853: isr, imr);
854: #endif
855: return (1);
856: }
857: isr &= imr;
858:
859: if (isr & IIPCHG) {
860: unsigned int ip, ipcr;
861:
862: ip = dart_read(sc, DART_IP);
863: ipcr = dart_read(sc, DART_IPCR);
864: dartmodemtrans(sc, ip, ipcr);
865: return (1);
866: }
867:
868: if (isr & (IRXRDYA | ITXRDYA))
869: port = 0;
870: else if (isr & (IRXRDYB | ITXRDYB))
871: port = 1;
872: else {
873: printf("dartintr: spurious interrupt, isr 0x%08x\n", isr);
874: return (1); /* claim it anyway */
875: }
876:
877: if (isr & (IRXRDYA | IRXRDYB)) {
878: dartrint(sc, port);
879: }
880: if (isr & (ITXRDYA | ITXRDYB)) {
881: dartxint(sc, port);
882: }
883: if ((port == A_PORT && (isr & IBRKA)) ||
884: (port == B_PORT && (isr & IBRKB))) {
885: dart_write(sc, port ? DART_CRB : DART_CRA, BRKINTRESET);
886: }
887:
888: return (1);
889: }
890:
891: /*
892: * Console interface routines.
893: * Since we select the actual console after all devices are attached,
894: * we can safely pick the appropriate softc and use its information.
895: */
896:
897: void
898: dartcnprobe(struct consdev *cp)
899: {
900: int maj;
901:
902: if (brdtyp != BRD_188 || badaddr(DART_BASE, 4) != 0)
903: return;
904:
905: /* do not attach as console if dart has been disabled */
906: if (dart_cd.cd_ndevs == 0 || dart_cd.cd_devs[0] == NULL)
907: return;
908:
909: /* locate the major number */
910: for (maj = 0; maj < nchrdev; maj++)
911: if (cdevsw[maj].d_open == dartopen)
912: break;
913: if (maj == nchrdev)
914: return;
915:
916: cp->cn_dev = makedev(maj, CONS_PORT);
917: cp->cn_pri = CN_NORMAL;
918: }
919:
920: void
921: dartcninit(cp)
922: struct consdev *cp;
923: {
924: }
925:
926: void
927: dartcnputc(dev_t dev, int c)
928: {
929: struct dartsoftc *sc;
930: int s;
931: int port;
932: bus_addr_t ptaddr;
933:
934: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
935: port = DART_PORT(dev);
936: ptaddr = port ? DART_B_BASE : DART_A_BASE;
937:
938: s = spltty();
939:
940: /* inhibit interrupts on the chip */
941: dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr & ~ITXRDYA);
942: /* make sure transmitter is enabled */
943: DELAY_CR;
944: dart_write(sc, ptaddr + DART_CRA, TXEN);
945:
946: while ((dart_read(sc, ptaddr + DART_SRA) & TXRDY) == 0)
947: ;
948: dart_write(sc, ptaddr + DART_TBA, c);
949:
950: /* wait for transmitter to empty */
951: while ((dart_read(sc, ptaddr + DART_SRA) & TXEMT) == 0)
952: ;
953:
954: /* restore the previous state */
955: dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
956: DELAY_CR;
957: dart_write(sc, ptaddr + DART_CRA, sc->sc_sv_reg.sv_cr[0]);
958:
959: splx(s);
960: }
961:
962: int
963: dartcngetc(dev_t dev)
964: {
965: struct dartsoftc *sc;
966: unsigned char sr; /* status reg of port a/b */
967: u_char c; /* received character */
968: int s;
969: int port;
970: bus_addr_t ptaddr;
971:
972: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
973: port = DART_PORT(dev);
974: ptaddr = port ? DART_B_BASE : DART_A_BASE;
975:
976: s = spltty();
977:
978: /* enable receiver */
979: dart_write(sc, ptaddr + DART_CRA, RXEN);
980:
981: for (;;) {
982: /* read status reg */
983: sr = dart_read(sc, ptaddr + DART_SRA);
984:
985: /* receiver interrupt handler*/
986: if (sr & RXRDY) {
987: /* read character from port */
988: c = dart_read(sc, ptaddr + DART_RBA);
989:
990: /* check break condition */
991: if (sr & RBRK) {
992: /* clear break state */
993: dart_write(sc, ptaddr + DART_CRA, BRKINTRESET);
994: DELAY_CR;
995: dart_write(sc, ptaddr + DART_CRA, ERRRESET);
996: break;
997: }
998:
999: if (sr & (FRERR | PERR | ROVRN)) {
1000: /* clear error state */
1001: dart_write(sc, ptaddr + DART_CRA, ERRRESET);
1002: DELAY_CR;
1003: dart_write(sc, ptaddr + DART_CRA, BRKINTRESET);
1004: } else {
1005: break;
1006: }
1007: }
1008: }
1009: splx(s);
1010:
1011: return ((int)c);
1012: }
CVSweb