1 /* 2 * Copyright (c) 1982 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)cons.c 6.3 (Berkeley) 06/08/85 7 */ 8 9 /* 10 * VAX console driver (and floppy interface) 11 */ 12 #include "param.h" 13 #include "conf.h" 14 #include "dir.h" 15 #include "user.h" 16 #include "proc.h" 17 #include "ioctl.h" 18 #include "tty.h" 19 #include "systm.h" 20 #include "uio.h" 21 22 #include "cpu.h" 23 #include "cons.h" 24 #include "mtpr.h" 25 26 struct tty cons; 27 int cnstart(); 28 int ttrstrt(); 29 char partab[]; 30 31 /*ARGSUSED*/ 32 cnopen(dev, flag) 33 dev_t dev; 34 { 35 register struct tty *tp = &cons; 36 37 tp->t_oproc = cnstart; 38 if ((tp->t_state&TS_ISOPEN) == 0) { 39 ttychars(tp); 40 tp->t_state = TS_ISOPEN|TS_CARR_ON; 41 tp->t_flags = EVENP|ECHO|XTABS|CRMOD; 42 } 43 if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 44 return (EBUSY); 45 mtpr(RXCS, mfpr(RXCS)|RXCS_IE); 46 mtpr(TXCS, mfpr(TXCS)|TXCS_IE); 47 return ((*linesw[tp->t_line].l_open)(dev, tp)); 48 } 49 50 /*ARGSUSED*/ 51 cnclose(dev) 52 dev_t dev; 53 { 54 register struct tty *tp = &cons; 55 56 (*linesw[tp->t_line].l_close)(tp); 57 ttyclose(tp); 58 } 59 60 /*ARGSUSED*/ 61 cnread(dev, uio) 62 dev_t dev; 63 struct uio *uio; 64 { 65 register struct tty *tp = &cons; 66 67 return ((*linesw[tp->t_line].l_read)(tp, uio)); 68 } 69 70 /*ARGSUSED*/ 71 cnwrite(dev, uio) 72 dev_t dev; 73 struct uio *uio; 74 { 75 register struct tty *tp = &cons; 76 77 return ((*linesw[tp->t_line].l_write)(tp, uio)); 78 } 79 80 /* 81 * Got a level-20 receive interrupt - 82 * the LSI wants to give us a character. 83 * Catch the character, and see who it goes to. 84 */ 85 /*ARGSUSED*/ 86 cnrint(dev) 87 dev_t dev; 88 { 89 register int c; 90 register struct tty *tp; 91 92 c = mfpr(RXDB); 93 if (c&RXDB_ID) { 94 #if VAX780 95 if (cpu == VAX_780) 96 cnrfl(c); 97 #endif 98 return; 99 } 100 tp = &cons; 101 (*linesw[tp->t_line].l_rint)(c, tp); 102 } 103 104 /*ARGSUSED*/ 105 cnioctl(dev, cmd, addr, flag) 106 dev_t dev; 107 caddr_t addr; 108 { 109 register struct tty *tp = &cons; 110 int error; 111 112 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 113 if (error >= 0) 114 return (error); 115 error = ttioctl(tp, cmd, addr, flag); 116 if (error < 0) 117 error = ENOTTY; 118 return (error); 119 } 120 121 int consdone = 1; 122 /* 123 * Got a level-20 transmission interrupt - 124 * the LSI wants another character. First, 125 * see if we can send something to the typewriter. 126 * If not, try the floppy. 127 */ 128 /*ARGSUSED*/ 129 cnxint(dev) 130 dev_t dev; 131 { 132 register struct tty *tp = &cons; 133 134 consdone++; 135 tp->t_state &= ~TS_BUSY; 136 if (tp->t_line) 137 (*linesw[tp->t_line].l_start)(tp); 138 else 139 cnstart(tp); 140 #if VAX780 141 if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0) 142 conxfl(); 143 #endif 144 } 145 146 cnstart(tp) 147 register struct tty *tp; 148 { 149 register int c, s; 150 151 s = spl5(); 152 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 153 goto out; 154 if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 155 if (tp->t_state&TS_ASLEEP) { 156 tp->t_state &= ~TS_ASLEEP; 157 wakeup((caddr_t)&tp->t_outq); 158 } 159 if (tp->t_wsel) { 160 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 161 tp->t_wsel = 0; 162 tp->t_state &= ~TS_WCOLL; 163 } 164 } 165 if (tp->t_outq.c_cc == 0) 166 goto out; 167 if (consdone == 0) 168 return; 169 c = getc(&tp->t_outq); 170 if (tp->t_flags&(RAW|LITOUT)) 171 mtpr(TXDB, c&0xff); 172 else if (c <= 0177) 173 mtpr(TXDB, (c | (partab[c]&0200))&0xff); 174 else { 175 timeout(ttrstrt, (caddr_t)tp, (c&0177)); 176 tp->t_state |= TS_TIMEOUT; 177 goto out; 178 } 179 consdone = 0; 180 tp->t_state |= TS_BUSY; 181 out: 182 splx(s); 183 } 184 185 /* 186 * Print a character on console. 187 * Attempts to save and restore device 188 * status. 189 */ 190 cnputc(c) 191 register int c; 192 { 193 register int s, timo; 194 195 timo = 30000; 196 /* 197 * Try waiting for the console tty to come ready, 198 * otherwise give up after a reasonable time. 199 */ 200 while ((mfpr(TXCS)&TXCS_RDY) == 0) 201 if(--timo == 0) 202 break; 203 if (c == 0) 204 return; 205 s = mfpr(TXCS); 206 mtpr(TXCS, 0); 207 mtpr(TXDB, c&0xff); 208 if (c == '\n') 209 cnputc('\r'); 210 cnputc(0); 211 mtpr(TXCS, s); 212 } 213