1: /* 2: * SCCS id @(#)dc.c 2.1 (Berkeley) 8/5/83 3: */ 4: 5: #include "dc.h" 6: #if NDC > 0 7: #include "param.h" 8: #include <sys/conf.h> 9: #include <sys/dir.h> 10: #include <sys/user.h> 11: #include <sys/tty.h> 12: #include <sys/systm.h> 13: #include <sys/dcreg.h> 14: 15: struct tty dc11[NDC]; 16: extern struct dcdevice *DCADDR; 17: 18: /* 19: * Input-side speed and control bit table. 20: * Each DC11 has 4 speeds which correspond to the 4 non-zero entries. 21: * The table index is the same as the speed-selector 22: * number for the DH11. 23: * Attempts to set the speed to a zero entry are ignored. 24: */ 25: short dcrstab[] = { 26: 0, /* 0 baud */ 27: 0, /* 50 baud */ 28: 0, /* 75 baud */ 29: 0, /* 110 baud */ 30: DC_7BITS | DC_IE | DC_SPEED0 | DC_DTR, /* 134.5 baud */ 31: DC_8BITS | DC_IE | DC_SPEED1 | DC_DTR, /* 150 baud */ 32: 0, /* 200 baud */ 33: DC_8BITS | DC_IE | DC_SPEED2 | DC_DTR, /* 300 baud */ 34: 0, /* 600 baud */ 35: DC_8BITS | DC_IE | DC_SPEED3 | DC_DTR, /* 1200 baud */ 36: 0, /* 1800 baud */ 37: 0, /* 2400 baud */ 38: 0, /* 4800 baud */ 39: 0, /* 9600 baud */ 40: 0, /* X0 */ 41: 0 /* X1 */ 42: }; 43: 44: /* 45: * Transmitter speed and control bit table 46: */ 47: short dctstab[] = { 48: 0, /* 0 baud */ 49: 0, /* 50 baud */ 50: 0, /* 75 baud */ 51: 0, /* 110 baud */ 52: DCTCSR_STOP1 | DCTCSR_TIE | DC_SPEED0 | DCTCSR_RTS, /* 134.5 baud */ 53: DCTCSR_STOP1 | DCTCSR_TIE | DC_SPEED1 | DCTCSR_RTS, /* 150 baud */ 54: 0, /* 200 baud */ 55: DCTCSR_STOP1 | DCTCSR_TIE | DC_SPEED2 | DCTCSR_RTS, /* 300 baud */ 56: 0, /* 600 baud */ 57: DCTCSR_STOP1 | DCTCSR_TIE | DC_SPEED3 | DCTCSR_RTS, /* 1200 baud */ 58: 0, /* 1800 baud */ 59: 0, /* 2400 baud */ 60: 0, /* 4800 baud */ 61: 0, /* 9600 baud */ 62: 0, /* X0 */ 63: 0 /* X1 */ 64: }; 65: 66: /* 67: * Open a DC11, waiting until carrier is established. 68: * Default initial conditions are set up on the first open. 69: * T_state's CARR_ON bit is a pure copy of the hardware 70: * DC_CAR bit, and is only used to regularize 71: * carrier tests in general tty routines. 72: */ 73: /*ARGSUSED*/ 74: dcopen(dev, flag) 75: register dev_t dev; 76: { 77: register struct tty *tp; 78: register struct dcdevice *dcaddr; 79: extern klstart(); 80: int s; 81: 82: if (minor(dev) >= NDC) { 83: u.u_error = ENXIO; 84: return; 85: } 86: tp = &dc11[minor(dev)]; 87: dcaddr = DCADDR + minor(dev); 88: tp->t_addr = (caddr_t)dcaddr; 89: tp->t_state |= WOPEN; 90: s = spl5(); 91: dcaddr->dcrcsr |= DC_IE | DC_DTR; 92: if ((tp->t_state & ISOPEN) == 0) { 93: tp->t_iproc = NULL; 94: tp->t_oproc = klstart; /* Yes, I know, but it works. */ 95: ttychars(tp); 96: tp->t_ispeed = B300; 97: tp->t_ospeed = B300; 98: tp->t_flags = ODDP | EVENP | ECHO; 99: dcaddr->dcrcsr = dcrstab[B300]; 100: dcaddr->dctcsr = dctstab[B300]; 101: } 102: if (dcaddr->dcrcsr & DC_CAR) 103: tp->t_state |= CARR_ON; 104: splx(s); 105: while ((tp->t_state & CARR_ON) == 0) 106: sleep((caddr_t)&tp->t_rawq, TTIPRI); 107: ttyopen(dev, tp); 108: } 109: 110: /* 111: * Close a DC11 112: */ 113: dcclose(dev) 114: dev_t dev; 115: { 116: register struct tty *tp; 117: 118: tp = &dc11[minor(dev)]; 119: if (tp->t_state & HUPCLS) 120: ((struct dcdevice *) (tp->t_addr))->dcrcsr & = ~DC_DTR; 121: ttyclose(tp); 122: } 123: 124: /* 125: * Read a DC11 126: */ 127: dcread(dev) 128: dev_t dev; 129: { 130: register struct tty *tp; 131: 132: tp = &dc11[minor(dev)]; 133: (*linesw[tp->t_line].l_read)(tp); 134: } 135: 136: /* 137: * Write a DC11 138: */ 139: dcwrite(dev) 140: dev_t dev; 141: { 142: register struct tty *tp; 143: 144: tp = &dc11[minor(dev)]; 145: (*linesw[tp->t_line].l_write)(tp); 146: } 147: 148: /* 149: * DC11 transmitter interrupt. 150: */ 151: dcxint(dev) 152: dev_t dev; 153: { 154: register struct tty *tp; 155: register struct clist *cp; 156: 157: tp = &dc11[minor(dev)]; 158: cp = &(tp->t_outq); 159: ttstart(tp); 160: if ((cp->c_cc == 0) || (cp->c_cc == TTLOWAT(tp))) 161: wakeup((caddr_t) cp); 162: } 163: 164: /* 165: * DC11 receiver interrupt. 166: */ 167: dcrint(dev) 168: dev_t dev; 169: { 170: register struct tty *tp; 171: register int c, csr; 172: 173: tp = &dc11[minor(dev)]; 174: c = ((struct dcdevice *) (tp->t_addr))->dcrbuf; 175: 176: /* 177: * If carrier is off, and an open is not in progress, 178: * knock down the CD lead to hang up the local dataset 179: * and signal a hangup. 180: */ 181: if (((csr = ((struct dcdevice *)(tp->t_addr))->dcrcsr) & DC_CAR) == 0) { 182: if ((tp->t_state & WOPEN) == 0) { 183: ((struct dcdevice *) (tp->t_addr))->dcrcsr &= ~DC_DTR; 184: if (tp->t_state & CARR_ON) 185: signal(tp->t_pgrp, SIGHUP); 186: flushtty(tp, FREAD|FWRITE); 187: } 188: tp->t_state &= ~CARR_ON; 189: return; 190: } 191: if ((tp->t_state & ISOPEN) == 0) { 192: if ((tp->t_state & WOPEN) && (csr & DC_CAR)) 193: tp->t_state |= CARR_ON; 194: wakeup((caddr_t) tp); 195: return; 196: } 197: if (csr & DC_BRK) 198: if (tp->t_flags & RAW) 199: c = 0; 200: else 201: c = 0177; 202: csr &= DC_PCHK; 203: if ((csr && ((tp->t_flags & (EVENP | ODDP)) == ODDP)) || 204: (!csr && ((tp->t_flags & (EVENP | ODDP)) == EVENP))) 205: (*linesw[tp->t_line].l_input)(c, tp); 206: } 207: 208: /* 209: * DC11 stty/gtty. 210: * Perform general functions and set speeds. 211: */ 212: dcioctl(dev, cmd, addr, flag) 213: dev_t dev; 214: caddr_t addr; 215: { 216: register struct tty *tp; 217: register r; 218: 219: tp = &dc11[minor(dev)]; 220: if (ttioctl(cmd, tp, addr, dev, flag) == 0) { 221: u.u_error = ENOTTY; 222: return; 223: } 224: if (cmd == TIOCSETP) { 225: r = dcrstab[tp->t_ispeed]; 226: if (r) 227: ((struct dcdevice *) (tp->t_addr))->dcrcsr = r; 228: else 229: ((struct dcdevice *) (tp->t_addr))->dcrcsr &= ~DC_DTR; 230: r = dctstab[tp->t_ospeed]; 231: ((struct dcdevice *) (tp->t_addr))->dctcsr = r; 232: } 233: else 234: u.u_error = ENOTTY; 235: } 236: #endif NDC