1 /* cons.c 4.3 12/17/80 */ 2 3 /* 4 * Vax console driver and floppy interface 5 */ 6 #include "../h/param.h" 7 #include "../h/conf.h" 8 #include "../h/dir.h" 9 #include "../h/user.h" 10 #include "../h/tty.h" 11 #include "../h/systm.h" 12 #include "../h/cons.h" 13 #include "../h/mtpr.h" 14 #include "../h/mx.h" 15 16 /* 17 * When running dz's using only SAE (silo alarm) on input 18 * it is necessary to call dzrint() at clock interrupt time. 19 * This is unsafe unless spl5()s in tty code are changed to 20 * spl6()s to block clock interrupts. Note that the dh driver 21 * currently in use works the same way as the dz, even though 22 * we could try to more intelligently manage its silo. 23 * Thus don't take this out if you have no dz's unless you 24 * change clock.c and dhtimer(). 25 */ 26 #define spl5 spl6 27 28 #define NL1 000400 29 #define NL2 001000 30 #define CR2 020000 31 #define FF1 040000 32 #define TAB1 002000 33 34 struct tty cons; 35 int cnstart(); 36 int ttrstrt(); 37 char partab[]; 38 39 /*ARGSUSED*/ 40 cnopen(dev, flag) 41 dev_t dev; 42 { 43 register struct tty *tp; 44 45 tp = &cons; 46 tp->t_oproc = cnstart; 47 tp->t_iproc = NULL; 48 if ((tp->t_state&ISOPEN) == 0) { 49 ttychars(tp); 50 tp->t_state = ISOPEN|CARR_ON; 51 tp->t_flags = EVENP|ECHO|XTABS|CRMOD; 52 } 53 if (tp->t_state&XCLUDE && u.u_uid != 0) { 54 u.u_error = EBUSY; 55 return; 56 } 57 mtpr(RXCS, mfpr(RXCS)|RXCS_IE); 58 mtpr(TXCS, mfpr(TXCS)|TXCS_IE); 59 (*linesw[tp->t_line].l_open)(dev, tp); 60 } 61 62 /*ARGSUSED*/ 63 cnclose(dev) 64 dev_t dev; 65 { 66 register struct tty *tp; 67 68 tp = &cons; 69 (*linesw[tp->t_line].l_close)(tp); 70 ttyclose(tp); 71 } 72 73 /*ARGSUSED*/ 74 cnread(dev) 75 dev_t dev; 76 { 77 register struct tty *tp; 78 79 tp = &cons; 80 (*linesw[tp->t_line].l_read)(tp); 81 } 82 83 /*ARGSUSED*/ 84 cnwrite(dev) 85 dev_t dev; 86 { 87 register struct tty *tp; 88 89 tp = &cons; 90 (*linesw[tp->t_line].l_write)(tp); 91 } 92 93 /* 94 * Got a level-20 receive interrupt - 95 * the LSI wants to give us a character. 96 * Catch the character, and see who it goes to. 97 */ 98 /*ARGSUSED*/ 99 cnrint(dev) 100 dev_t dev; 101 { 102 register int c; 103 register struct tty *tp; 104 105 c = mfpr(RXDB); 106 if (c&RXDB_ID) { 107 #if VAX==780 108 cnrfl(c); 109 #endif 110 return; 111 } 112 tp = &cons; 113 (*linesw[tp->t_line].l_rint)(c, tp); 114 } 115 116 /*ARGSUSED*/ 117 cnioctl(dev, cmd, addr, flag) 118 dev_t dev; 119 caddr_t addr; 120 { 121 register struct tty *tp; 122 123 tp = &cons; 124 cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 125 if (cmd == 0) 126 return; 127 if (ttioctl(tp, cmd, addr, flag) == 0) 128 u.u_error = ENOTTY; 129 } 130 131 #if VAX==750 132 int consdone = 1; 133 #endif 134 /* 135 * Got a level-20 transmission interrupt - 136 * the LSI wants another character. First, 137 * see if we can send something to the typewriter. 138 * If not, try the floppy. 139 */ 140 /*ARGSUSED*/ 141 cnxint(dev) 142 dev_t dev; 143 { 144 register struct tty *tp; 145 146 #if VAX==750 147 consdone++; 148 #endif 149 tp = &cons; 150 tp->t_state &= ~BUSY; 151 if (tp->t_line) 152 (*linesw[tp->t_line].l_start)(tp); 153 else 154 cnstart(tp); 155 #if VAX==780 156 if ((tp->t_state & BUSY) == 0) 157 conxfl(); 158 #endif 159 } 160 161 cnstart(tp) 162 register struct tty *tp; 163 { 164 register c; 165 register s; 166 167 s = spl5(); 168 if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) 169 goto out; 170 if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) { 171 tp->t_state &= ~ASLEEP; 172 if (tp->t_chan) 173 mcstart(tp->t_chan, (caddr_t)&tp->t_outq); 174 else 175 wakeup((caddr_t)&tp->t_outq); 176 } 177 if (tp->t_outq.c_cc == 0) 178 goto out; 179 #if VAX==750 180 if (consdone == 0) 181 return; 182 #else 183 if ((mfpr(TXCS)&TXCS_RDY) == 0) 184 return; 185 #endif 186 if ((c=getc(&tp->t_outq)) >= 0) { 187 #if VAX==750 188 consdone = 0; 189 #endif 190 if (tp->t_flags&RAW) 191 mtpr(TXDB, c&0xff); 192 else if (c<=0177) 193 mtpr(TXDB, (c | (partab[c]&0200))&0xff); 194 else { 195 timeout(ttrstrt, (caddr_t)tp, (c&0177)); 196 tp->t_state |= TIMEOUT; 197 goto out; 198 } 199 } 200 tp->t_state |= BUSY; 201 out: 202 splx(s); 203 } 204 205 /* 206 * Print a character on console. 207 * Attempts to save and restore device 208 * status. 209 */ 210 cnputc(c) 211 register c; 212 { 213 register s, timo; 214 215 timo = 30000; 216 /* 217 * Try waiting for the console tty to come ready, 218 * otherwise give up after a reasonable time. 219 */ 220 while((mfpr(TXCS)&TXCS_RDY) == 0) 221 if(--timo == 0) 222 break; 223 if(c == 0) 224 return; 225 s = mfpr(TXCS); 226 mtpr(TXCS, 0); 227 mtpr(TXDB, c&0xff); 228 if(c == '\n') 229 cnputc('\r'); 230 cnputc(0); 231 mtpr(TXCS, s); 232 } 233