1 /* dz.c 3.16 09/27/80 */ 2 3 /* 4 * DZ-11 Driver 5 */ 6 #include "../h/param.h" 7 #include "../h/systm.h" 8 #include "../h/tty.h" 9 #include "../h/dir.h" 10 #include "../h/user.h" 11 #include "../h/map.h" 12 #include "../h/pte.h" 13 #include "../h/uba.h" 14 #include "../h/conf.h" 15 #include "../h/pdma.h" 16 #include "../h/bk.h" 17 #include "../h/file.h" 18 19 /* 20 * When running dz's using only SAE (silo alarm) on input 21 * it is necessary to call dzrint() at clock interrupt time. 22 * This is unsafe unless spl5()s in tty code are changed to 23 * spl6()s to block clock interrupts. Note that the dh driver 24 * currently in use works the same way as the dz, even though 25 * we could try to more intelligently manage its silo. 26 * Thus don't take this out if you have no dz's unless you 27 * change clock.c and dhtimer(). 28 */ 29 #define spl5 spl6 30 31 #define DZADDR (UBA0_DEV + 0160100) 32 #ifdef DISTRIB 33 #define NDZ11 1 34 #else 35 #define NDZ11 4 36 #endif 37 #define NDZ (NDZ11*8) 38 39 #define BITS7 020 40 #define BITS8 030 41 #define TWOSB 040 42 #define PENABLE 0100 43 #define OPAR 0200 44 #define MSE 040 /* Master Scan Enable */ 45 #define RIE 0100 /* Receiver Interrupt Enable */ 46 #define SAE 010000 /* Silo Alarm Enable */ 47 #define TIE 040000 /* Transmit Interrupt Enable */ 48 #define DZ_IEN (MSE+RIE+TIE+SAE) 49 #define PERROR 010000 50 #define FRERROR 020000 51 #define OVERRUN 040000 52 #define SSPEED 7 /* std speed = 300 baud */ 53 54 55 #define dzlpr dzrbuf 56 #define dzmsr dzbrk 57 #define ON 1 58 #define OFF 0 59 60 int dzstart(); 61 int dzxint(); 62 int ttrstrt(); 63 struct tty dz_tty[NDZ]; 64 int dz_cnt = { NDZ }; 65 int dzact; 66 int dzinit; 67 68 struct device { 69 short dzcsr; 70 short dzrbuf; 71 char dztcr; 72 char dzdtr; 73 char dztbuf; 74 char dzbrk; 75 }; 76 77 struct pdma dzpdma[] = { 78 (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[0], dzxint, 79 (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[1], dzxint, 80 (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[2], dzxint, 81 (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[3], dzxint, 82 (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[4], dzxint, 83 (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[5], dzxint, 84 (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[6], dzxint, 85 (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[7], dzxint, 86 #if NDZ >= 2 87 (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[8], dzxint, 88 (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[9], dzxint, 89 (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[10], dzxint, 90 (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[11], dzxint, 91 (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[12], dzxint, 92 (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[13], dzxint, 93 (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[14], dzxint, 94 (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[15], dzxint, 95 #endif 96 #if NDZ >= 3 97 (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[16], dzxint, 98 (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[17], dzxint, 99 (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[18], dzxint, 100 (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[19], dzxint, 101 (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[20], dzxint, 102 (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[21], dzxint, 103 (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[22], dzxint, 104 (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[23], dzxint, 105 #endif 106 #if NDZ >= 4 107 (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[24], dzxint, 108 (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[25], dzxint, 109 (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[26], dzxint, 110 (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[27], dzxint, 111 (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[28], dzxint, 112 (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[29], dzxint, 113 (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[30], dzxint, 114 (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[31], dzxint, 115 #endif 116 }; 117 char dz_timer; 118 char dz_speeds[] = { 119 0, 020 , 021 , 022 , 023 , 024 , 0, 025, 120 026 , 027 , 030 , 032 , 034 , 036 , 0 , 0, 121 }; 122 123 /*ARGSUSED*/ 124 dzopen(d, flag) 125 { 126 register struct tty *tp; 127 register dev; 128 extern dzscan(); 129 130 dev = minor(d); 131 if (dev >= dz_cnt) { 132 u.u_error = ENXIO; 133 return; 134 } 135 if (dz_timer == 0) { 136 dz_timer++; 137 timeout(dzscan, (caddr_t)0, 60); 138 } 139 tp = &dz_tty[dev]; 140 tp->t_addr = (caddr_t)&dzpdma[dev]; 141 tp->t_oproc = dzstart; 142 tp->t_iproc = NULL; 143 tp->t_state |= WOPEN; 144 if ((tp->t_state & ISOPEN) == 0) { 145 ttychars(tp); 146 tp->t_ospeed = tp->t_ispeed = SSPEED; 147 tp->t_flags = ODDP|EVENP|ECHO; 148 /*tp->t_state |= HUPCLS;*/ 149 dzparam(dev); 150 } else if (tp->t_state&XCLUDE && u.u_uid != 0) { 151 u.u_error = EBUSY; 152 return; 153 } 154 dzmodem(dev, ON); 155 (void) spl5(); 156 while ((tp->t_state & CARR_ON) == 0) { 157 tp->t_state |= WOPEN; 158 sleep((caddr_t)&tp->t_rawq, TTIPRI); 159 } 160 (void) spl0(); 161 (*linesw[tp->t_line].l_open)(d, tp); 162 } 163 164 dzclose(d) 165 { 166 register struct tty *tp; 167 register dev; 168 169 dev = minor(d); 170 tp = &dz_tty[dev]; 171 (*linesw[tp->t_line].l_close)(tp); 172 if (tp->t_state & HUPCLS) 173 dzmodem(dev, OFF); 174 ttyclose(tp); 175 } 176 177 dzread(d) 178 { 179 register struct tty *tp; 180 181 tp = &dz_tty[minor(d)]; 182 (*linesw[tp->t_line].l_read)(tp); 183 } 184 185 dzwrite(d) 186 { 187 register struct tty *tp; 188 189 tp = &dz_tty[minor(d)]; 190 (*linesw[tp->t_line].l_write)(tp); 191 } 192 193 /*ARGSUSED*/ 194 dzrint(dev) 195 { 196 register struct tty *tp; 197 register int c; 198 register struct device *dzaddr; 199 register struct tty *tp0; 200 int s; 201 202 s = spl6(); /* see comment in clock.c */ 203 /* as long as we are here, service them all */ 204 for (dev = 0; dev < NDZ; dev += 8) { 205 if ((dzact & (1<<(dev>>3))) == 0) 206 continue; 207 dzaddr = dzpdma[dev].p_addr; 208 tp0 = &dz_tty[dev]; 209 while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 210 tp = tp0 + ((c>>8)&07); 211 if (tp >= &dz_tty[dz_cnt]) 212 continue; 213 if ((tp->t_state & ISOPEN) == 0) { 214 wakeup((caddr_t)&tp->t_rawq); 215 continue; 216 } 217 if (c&FRERROR) 218 /* framing error = break */ 219 if (tp->t_flags & RAW) 220 c = 0; /* null for getty */ 221 else 222 #ifdef IIASA 223 continue; 224 #else 225 c = tun.t_intrc; 226 #endif 227 if (c&OVERRUN) 228 printf("o"); 229 if (c&PERROR) 230 /* parity error */ 231 if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 232 || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 233 continue; 234 if (tp->t_line == NETLDISC) { 235 c &= 0177; 236 BKINPUT(c, tp); 237 } else 238 (*linesw[tp->t_line].l_rint)(c, tp); 239 } 240 } 241 splx(s); 242 } 243 244 /*ARGSUSED*/ 245 dzioctl(dev, cmd, addr, flag) 246 caddr_t addr; 247 dev_t dev; 248 { 249 register struct tty *tp; 250 static char dz_brk[NDZ11]; 251 252 tp = &dz_tty[minor(dev)]; 253 cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 254 if (cmd == 0) 255 return; 256 if (ttioctl(cmd, tp, addr, dev, flag)) { 257 if (cmd==TIOCSETP || cmd==TIOCSETN) 258 dzparam(minor(dev)); 259 } else switch(cmd) { 260 case TIOCSBRK: 261 ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = 262 (dz_brk[minor(dev)>>3] |= 1 << (dev&07)); 263 break; 264 case TIOCCBRK: 265 ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = 266 (dz_brk[minor(dev)>>3] &= ~(1 << (dev&07))); 267 break; 268 case TIOCSDTR: 269 dzmodem(minor(dev), ON); 270 break; 271 case TIOCCDTR: 272 dzmodem(minor(dev), OFF); 273 break; 274 default: 275 u.u_error = ENOTTY; 276 } 277 } 278 279 dzparam(dev) 280 { 281 register struct tty *tp; 282 register struct device *dzaddr; 283 register short lpr; 284 285 tp = &dz_tty[dev]; 286 dzaddr = dzpdma[dev].p_addr; 287 dzaddr->dzcsr = DZ_IEN; 288 dzact |= (1<<(dev>>3)); 289 if (tp->t_ispeed == 0) { 290 dzmodem(dev, OFF); /* hang up line */ 291 return; 292 } 293 lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07); 294 #ifndef IIASA 295 if (tp->t_flags & RAW) 296 lpr |= BITS8; 297 else 298 lpr |= (BITS7|PENABLE); 299 if ((tp->t_flags & EVENP) == 0) 300 lpr |= OPAR; 301 #else IIASA 302 if ((tp->t_flags & (EVENP|ODDP)) == (EVENP|ODDP)) 303 lpr |= BITS8; 304 else if (tp->t_flags & EVENP) 305 lpr |= (BITS7|PENABLE); 306 else if (tp->t_flags & ODDP) 307 lpr |= (BITS7|OPAR|PENABLE); 308 else 309 lpr |= BITS7; 310 #endif IIASA 311 if (tp->t_ispeed == 3) 312 lpr |= TWOSB; /* 110 baud: 2 stop bits */ 313 dzaddr->dzlpr = lpr; 314 } 315 316 dzxint(tp) 317 register struct tty *tp; 318 { 319 register struct pdma *dp; 320 register s; 321 s = spl6(); /* block the clock */ 322 323 dp = &dzpdma[tp-dz_tty]; 324 tp->t_state &= ~BUSY; 325 if (tp->t_state & FLUSH) 326 tp->t_state &= ~FLUSH; 327 else 328 ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 329 if (tp->t_line) 330 (*linesw[tp->t_line].l_start)(tp); 331 else 332 dzstart(tp); 333 if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0) 334 dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8)); 335 splx(s); 336 } 337 338 dzstart(tp) 339 register struct tty *tp; 340 { 341 register struct pdma *dp; 342 register struct device *dzaddr; 343 register cc; 344 int sps; 345 346 dp = &dzpdma[tp-dz_tty]; 347 dzaddr = dp->p_addr; 348 sps = spl5(); 349 if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) 350 goto out; 351 if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) { 352 tp->t_state &= ~ASLEEP; 353 if (tp->t_chan) 354 mcstart(tp->t_chan, (caddr_t)&tp->t_outq); 355 else 356 wakeup((caddr_t)&tp->t_outq); 357 } 358 if (tp->t_outq.c_cc == 0) 359 goto out; 360 if (tp->t_flags&RAW) 361 cc = ndqb(&tp->t_outq, 0); 362 else { 363 cc = ndqb(&tp->t_outq, 0200); 364 if (cc == 0) { 365 cc = getc(&tp->t_outq); 366 timeout(ttrstrt, (caddr_t)tp, (cc&0177) + 6); 367 tp->t_state |= TIMEOUT; 368 goto out; 369 } 370 } 371 tp->t_state |= BUSY; 372 dp->p_end = dp->p_mem = tp->t_outq.c_cf; 373 dp->p_end += cc; 374 dzaddr->dztcr |= 1 << ((tp-dz_tty) % 8); 375 out: 376 splx(sps); 377 } 378 379 /* 380 * Stop output on a line. 381 * Assume call is made at spl6. 382 */ 383 /*ARGSUSED*/ 384 dzstop(tp, flag) 385 register struct tty *tp; 386 { 387 register struct pdma *dp; 388 register int s; 389 390 dp = &dzpdma[tp-dz_tty]; 391 s = spl6(); 392 if (tp->t_state & BUSY) { 393 dp->p_end = dp->p_mem; 394 if ((tp->t_state&TTSTOP)==0) { 395 tp->t_state |= FLUSH; 396 } 397 } 398 splx(s); 399 } 400 401 dzmodem(dev, flag) 402 register int dev; 403 { 404 register struct device *dzaddr; 405 register char bit; 406 407 dzaddr = dzpdma[dev].p_addr; 408 bit = 1<<(dev&07); 409 if (flag == OFF) 410 dzaddr->dzdtr &= ~bit; 411 else 412 dzaddr->dzdtr |= bit; 413 } 414 415 dzscan() 416 { 417 register i; 418 register struct device *dzaddr; 419 register bit; 420 register struct tty *tp; 421 422 for (i = 0; i < dz_cnt ; i++) { 423 dzaddr = dzpdma[i].p_addr; 424 tp = &dz_tty[i]; 425 bit = 1<<(i&07); 426 if (dzaddr->dzmsr & bit) { 427 /* carrier present */ 428 if ((tp->t_state & CARR_ON) == 0) { 429 wakeup((caddr_t)&tp->t_rawq); 430 tp->t_state |= CARR_ON; 431 } 432 } else { 433 if ((tp->t_state&CARR_ON) && (tp->t_local&LNOHANG) == 0) { 434 /* carrier lost */ 435 if (tp->t_state&ISOPEN) { 436 gsignal(tp->t_pgrp, SIGHUP); 437 gsignal(tp->t_pgrp, SIGCONT); 438 dzaddr->dzdtr &= ~bit; 439 flushtty(tp, FREAD|FWRITE); 440 } 441 tp->t_state &= ~CARR_ON; 442 } 443 } 444 } 445 timeout(dzscan, (caddr_t)0, 2*HZ); 446 } 447 448 dztimer() 449 { 450 451 dzrint(0); 452 } 453 454 /* 455 * Reset state of driver if UBA reset was necessary. 456 * Reset parameters and restart transmission on open lines. 457 */ 458 dzreset() 459 { 460 int d; 461 register struct tty *tp; 462 463 printf(" dz"); 464 for (d = 0; d < NDZ; d++) { 465 tp = &dz_tty[d]; 466 if (tp->t_state & (ISOPEN|WOPEN)) { 467 dzparam(d); 468 dzmodem(d, ON); 469 tp->t_state &= ~BUSY; 470 dzstart(tp); 471 } 472 } 473 dztimer(); 474 } 475