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