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