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 * @(#)dz.c 6.11 (Berkeley) 04/12/86 7 */ 8 9 #include "dz.h" 10 #if NDZ > 0 11 /* 12 * DZ-11/DZ-32 Driver 13 * 14 * This driver mimics dh.c; see it for explanation of common code. 15 */ 16 #include "bk.h" 17 18 #include "../machine/pte.h" 19 20 #include "param.h" 21 #include "systm.h" 22 #include "ioctl.h" 23 #include "tty.h" 24 #include "dir.h" 25 #include "user.h" 26 #include "proc.h" 27 #include "map.h" 28 #include "buf.h" 29 #include "vm.h" 30 #include "conf.h" 31 #include "bkmac.h" 32 #include "file.h" 33 #include "uio.h" 34 #include "kernel.h" 35 #include "syslog.h" 36 37 #include "pdma.h" 38 #include "ubavar.h" 39 #include "dzreg.h" 40 41 /* 42 * Driver information for auto-configuration stuff. 43 */ 44 int dzprobe(), dzattach(), dzrint(); 45 struct uba_device *dzinfo[NDZ]; 46 u_short dzstd[] = { 0 }; 47 struct uba_driver dzdriver = 48 { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 49 50 #define NDZLINE (NDZ*8) 51 #define FASTTIMER (hz/30) /* rate to drain silos, when in use */ 52 53 int dzstart(), dzxint(), dzdma(); 54 int ttrstrt(); 55 struct tty dz_tty[NDZLINE]; 56 int dz_cnt = { NDZLINE }; 57 int dzact; 58 int dzsilos; /* mask of dz's with silo in use */ 59 int dzchars[NDZ]; /* recent input count */ 60 int dzrate[NDZ]; /* smoothed input count */ 61 int dztimerintvl; /* time interval for dztimer */ 62 int dzhighrate = 100; /* silo on if dzchars > dzhighrate */ 63 int dzlowrate = 75; /* silo off if dzrate < dzlowrate */ 64 65 #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 66 67 /* 68 * Software copy of dzbrk since it isn't readable 69 */ 70 char dz_brk[NDZ]; 71 char dzsoftCAR[NDZ]; 72 char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 73 74 /* 75 * The dz11 doesn't interrupt on carrier transitions, so 76 * we have to use a timer to watch it. 77 */ 78 char dz_timer; /* timer started? */ 79 80 /* 81 * Pdma structures for fast output code 82 */ 83 struct pdma dzpdma[NDZLINE]; 84 85 char dz_speeds[] = 86 { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 87 88 #ifndef PORTSELECTOR 89 #define ISPEED B9600 90 #define IFLAGS (EVENP|ODDP|ECHO) 91 #else 92 #define ISPEED B4800 93 #define IFLAGS (EVENP|ODDP) 94 #endif 95 96 dzprobe(reg) 97 caddr_t reg; 98 { 99 register int br, cvec; 100 register struct dzdevice *dzaddr = (struct dzdevice *)reg; 101 102 #ifdef lint 103 br = 0; cvec = br; br = cvec; 104 dzrint(0); dzxint((struct tty *)0); 105 #endif 106 dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 107 if (dzaddr->dzcsr & DZ_32) 108 dzaddr->dzlnen = 1; 109 else 110 dzaddr->dztcr = 1; /* enable any line */ 111 DELAY(100000); 112 dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 113 if (cvec && cvec != 0x200) 114 cvec -= 4; 115 return (sizeof (struct dzdevice)); 116 } 117 118 dzattach(ui) 119 register struct uba_device *ui; 120 { 121 register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 122 register struct tty *tp = &dz_tty[ui->ui_unit*8]; 123 register int cntr; 124 extern dzscan(); 125 126 for (cntr = 0; cntr < 8; cntr++) { 127 pdp->p_addr = (struct dzdevice *)ui->ui_addr; 128 pdp->p_arg = (int)tp; 129 pdp->p_fcn = dzxint; 130 pdp++, tp++; 131 } 132 dzsoftCAR[ui->ui_unit] = ui->ui_flags; 133 if (dz_timer == 0) { 134 dz_timer++; 135 timeout(dzscan, (caddr_t)0, hz); 136 dztimerintvl = FASTTIMER; 137 } 138 } 139 140 /*ARGSUSED*/ 141 dzopen(dev, flag) 142 dev_t dev; 143 { 144 register struct tty *tp; 145 register int unit; 146 147 unit = minor(dev); 148 if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) 149 return (ENXIO); 150 tp = &dz_tty[unit]; 151 tp->t_addr = (caddr_t)&dzpdma[unit]; 152 tp->t_oproc = dzstart; 153 if ((tp->t_state & TS_ISOPEN) == 0) { 154 ttychars(tp); 155 #ifndef PORTSELECTOR 156 if (tp->t_ispeed == 0) { 157 #else 158 tp->t_state |= TS_HUPCLS; 159 #endif PORTSELECTOR 160 tp->t_ispeed = ISPEED; 161 tp->t_ospeed = ISPEED; 162 tp->t_flags = IFLAGS; 163 #ifndef PORTSELECTOR 164 } 165 #endif PORTSELECTOR 166 dzparam(unit); 167 } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 168 return (EBUSY); 169 (void) dzmctl(dev, DZ_ON, DMSET); 170 (void) spl5(); 171 while ((tp->t_state & TS_CARR_ON) == 0) { 172 tp->t_state |= TS_WOPEN; 173 sleep((caddr_t)&tp->t_rawq, TTIPRI); 174 } 175 (void) spl0(); 176 return ((*linesw[tp->t_line].l_open)(dev, tp)); 177 } 178 179 /*ARGSUSED*/ 180 dzclose(dev, flag) 181 dev_t dev; 182 { 183 register struct tty *tp; 184 register int unit; 185 register struct dzdevice *dzaddr; 186 int dz; 187 188 unit = minor(dev); 189 dz = unit >> 3; 190 tp = &dz_tty[unit]; 191 (*linesw[tp->t_line].l_close)(tp); 192 dzaddr = dzpdma[unit].p_addr; 193 if (dzaddr->dzcsr&DZ_32) 194 (void) dzmctl(dev, DZ_BRK, DMBIC); 195 else 196 dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 197 if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) 198 (void) dzmctl(dev, DZ_OFF, DMSET); 199 ttyclose(tp); 200 } 201 202 dzread(dev, uio) 203 dev_t dev; 204 struct uio *uio; 205 { 206 register struct tty *tp; 207 208 tp = &dz_tty[minor(dev)]; 209 return ((*linesw[tp->t_line].l_read)(tp, uio)); 210 } 211 212 dzwrite(dev, uio) 213 dev_t dev; 214 struct uio *uio; 215 { 216 register struct tty *tp; 217 218 tp = &dz_tty[minor(dev)]; 219 return ((*linesw[tp->t_line].l_write)(tp, uio)); 220 } 221 222 /*ARGSUSED*/ 223 dzrint(dz) 224 int dz; 225 { 226 register struct tty *tp; 227 register int c; 228 register struct dzdevice *dzaddr; 229 register struct tty *tp0; 230 register int unit; 231 int overrun = 0; 232 233 if ((dzact & (1<<dz)) == 0) 234 return; 235 unit = dz * 8; 236 dzaddr = dzpdma[unit].p_addr; 237 tp0 = &dz_tty[unit]; 238 dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 239 dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 240 while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 241 c = dzaddr->dzmtsr; 242 tp = tp0 + (c&7); 243 if (tp >= &dz_tty[dz_cnt]) 244 break; 245 dzaddr->dzlcs = c&7; /* get status of modem lines */ 246 dzwait(dzaddr); /* wait for them */ 247 if (c & DZ_CD) /* carrier status change? */ 248 if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 249 /* carrier present */ 250 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 251 } else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0) 252 dzaddr->dzlcs = DZ_ACK|(c&7); 253 } 254 while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 255 dzchars[dz]++; 256 tp = tp0 + ((c>>8)&07); 257 if (tp >= &dz_tty[dz_cnt]) 258 continue; 259 if ((tp->t_state & TS_ISOPEN) == 0) { 260 wakeup((caddr_t)&tp->t_rawq); 261 #ifdef PORTSELECTOR 262 if ((tp->t_state&TS_WOPEN) == 0) 263 #endif 264 continue; 265 } 266 if (c&DZ_FE) 267 if (tp->t_flags & RAW) 268 c = 0; 269 else 270 c = tp->t_intrc; 271 if (c&DZ_DO && overrun == 0) { 272 log(LOG_WARNING, "dz%d,%d: silo overflow\n", dz, (c>>8)&7); 273 overrun = 1; 274 } 275 if (c&DZ_PE) 276 if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 277 || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 278 continue; 279 #if NBK > 0 280 if (tp->t_line == NETLDISC) { 281 c &= 0177; 282 BKINPUT(c, tp); 283 } else 284 #endif 285 (*linesw[tp->t_line].l_rint)(c, tp); 286 } 287 } 288 289 /*ARGSUSED*/ 290 dzioctl(dev, cmd, data, flag) 291 dev_t dev; 292 caddr_t data; 293 { 294 register struct tty *tp; 295 register int unit = minor(dev); 296 register int dz = unit >> 3; 297 register struct dzdevice *dzaddr; 298 int error; 299 300 tp = &dz_tty[unit]; 301 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 302 if (error >= 0) 303 return (error); 304 error = ttioctl(tp, cmd, data, flag); 305 if (error >= 0) { 306 if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS || 307 cmd == TIOCLBIC || cmd == TIOCLSET) 308 dzparam(unit); 309 return (error); 310 } 311 switch (cmd) { 312 313 case TIOCSBRK: 314 dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 315 if (dzaddr->dzcsr&DZ_32) 316 (void) dzmctl(dev, DZ_BRK, DMBIS); 317 else 318 dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 319 break; 320 321 case TIOCCBRK: 322 dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 323 if (dzaddr->dzcsr&DZ_32) 324 (void) dzmctl(dev, DZ_BRK, DMBIC); 325 else 326 dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 327 break; 328 329 case TIOCSDTR: 330 (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 331 break; 332 333 case TIOCCDTR: 334 (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 335 break; 336 337 case TIOCMSET: 338 (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 339 break; 340 341 case TIOCMBIS: 342 (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 343 break; 344 345 case TIOCMBIC: 346 (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 347 break; 348 349 case TIOCMGET: 350 *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 351 break; 352 353 default: 354 return (ENOTTY); 355 } 356 return (0); 357 } 358 359 dmtodz(bits) 360 register int bits; 361 { 362 register int b; 363 364 b = (bits >>1) & 0370; 365 if (bits & DML_ST) b |= DZ_ST; 366 if (bits & DML_RTS) b |= DZ_RTS; 367 if (bits & DML_DTR) b |= DZ_DTR; 368 if (bits & DML_LE) b |= DZ_LE; 369 return(b); 370 } 371 372 dztodm(bits) 373 register int bits; 374 { 375 register int b; 376 377 b = (bits << 1) & 0360; 378 if (bits & DZ_DSR) b |= DML_DSR; 379 if (bits & DZ_DTR) b |= DML_DTR; 380 if (bits & DZ_ST) b |= DML_ST; 381 if (bits & DZ_RTS) b |= DML_RTS; 382 return(b); 383 } 384 385 dzparam(unit) 386 register int unit; 387 { 388 register struct tty *tp; 389 register struct dzdevice *dzaddr; 390 register int lpr; 391 392 tp = &dz_tty[unit]; 393 dzaddr = dzpdma[unit].p_addr; 394 if (dzsilos & (1 << (unit >> 3))) 395 dzaddr->dzcsr = DZ_IEN | DZ_SAE; 396 else 397 dzaddr->dzcsr = DZ_IEN; 398 dzact |= (1<<(unit>>3)); 399 if (tp->t_ispeed == 0) { 400 (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 401 return; 402 } 403 lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 404 if (tp->t_flags & (RAW|LITOUT|PASS8)) 405 lpr |= BITS8; 406 else 407 lpr |= (BITS7|PENABLE); 408 if ((tp->t_flags & EVENP) == 0) 409 lpr |= OPAR; 410 if (tp->t_ispeed == B110) 411 lpr |= TWOSB; 412 dzaddr->dzlpr = lpr; 413 } 414 415 dzxint(tp) 416 register struct tty *tp; 417 { 418 register struct pdma *dp; 419 register dz, unit; 420 421 dp = (struct pdma *)tp->t_addr; 422 tp->t_state &= ~TS_BUSY; 423 if (tp->t_state & TS_FLUSH) 424 tp->t_state &= ~TS_FLUSH; 425 else { 426 ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 427 dp->p_end = dp->p_mem = tp->t_outq.c_cf; 428 } 429 if (tp->t_line) 430 (*linesw[tp->t_line].l_start)(tp); 431 else 432 dzstart(tp); 433 dz = minor(tp->t_dev) >> 3; 434 unit = minor(tp->t_dev) & 7; 435 if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 436 if (dp->p_addr->dzcsr & DZ_32) 437 dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 438 else 439 dp->p_addr->dztcr &= ~(1<<unit); 440 } 441 442 dzstart(tp) 443 register struct tty *tp; 444 { 445 register struct pdma *dp; 446 register struct dzdevice *dzaddr; 447 register int cc; 448 int s, dz, unit; 449 450 dp = (struct pdma *)tp->t_addr; 451 dzaddr = dp->p_addr; 452 s = spl5(); 453 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 454 goto out; 455 if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 456 if (tp->t_state&TS_ASLEEP) { 457 tp->t_state &= ~TS_ASLEEP; 458 wakeup((caddr_t)&tp->t_outq); 459 } 460 if (tp->t_wsel) { 461 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 462 tp->t_wsel = 0; 463 tp->t_state &= ~TS_WCOLL; 464 } 465 } 466 if (tp->t_outq.c_cc == 0) 467 goto out; 468 if (tp->t_flags & (RAW|LITOUT)) 469 cc = ndqb(&tp->t_outq, 0); 470 else { 471 cc = ndqb(&tp->t_outq, 0200); 472 if (cc == 0) { 473 cc = getc(&tp->t_outq); 474 timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 475 tp->t_state |= TS_TIMEOUT; 476 goto out; 477 } 478 } 479 tp->t_state |= TS_BUSY; 480 dp->p_end = dp->p_mem = tp->t_outq.c_cf; 481 dp->p_end += cc; 482 dz = minor(tp->t_dev) >> 3; 483 unit = minor(tp->t_dev) & 7; 484 if (dzaddr->dzcsr & DZ_32) 485 dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 486 else 487 dzaddr->dztcr |= (1<<unit); 488 out: 489 splx(s); 490 } 491 492 /* 493 * Stop output on a line. 494 */ 495 /*ARGSUSED*/ 496 dzstop(tp, flag) 497 register struct tty *tp; 498 { 499 register struct pdma *dp; 500 register int s; 501 502 dp = (struct pdma *)tp->t_addr; 503 s = spl5(); 504 if (tp->t_state & TS_BUSY) { 505 dp->p_end = dp->p_mem; 506 if ((tp->t_state&TS_TTSTOP)==0) 507 tp->t_state |= TS_FLUSH; 508 } 509 splx(s); 510 } 511 512 dzmctl(dev, bits, how) 513 dev_t dev; 514 int bits, how; 515 { 516 register struct dzdevice *dzaddr; 517 register int unit, mbits; 518 int b, s; 519 520 unit = minor(dev); 521 b = 1<<(unit&7); 522 dzaddr = dzpdma[unit].p_addr; 523 s = spl5(); 524 if (dzaddr->dzcsr & DZ_32) { 525 dzwait(dzaddr) 526 DELAY(100); /* IS 100 TOO MUCH? */ 527 dzaddr->dzlcs = unit&7; 528 DELAY(100); 529 dzwait(dzaddr) 530 DELAY(100); 531 mbits = dzaddr->dzlcs; 532 mbits &= 0177770; 533 } else { 534 mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 535 mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 536 mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 537 } 538 switch (how) { 539 case DMSET: 540 mbits = bits; 541 break; 542 543 case DMBIS: 544 mbits |= bits; 545 break; 546 547 case DMBIC: 548 mbits &= ~bits; 549 break; 550 551 case DMGET: 552 (void) splx(s); 553 return(mbits); 554 } 555 if (dzaddr->dzcsr & DZ_32) { 556 mbits |= DZ_ACK|(unit&7); 557 dzaddr->dzlcs = mbits; 558 } else { 559 if (mbits & DZ_DTR) 560 dzaddr->dzdtr |= b; 561 else 562 dzaddr->dzdtr &= ~b; 563 } 564 (void) splx(s); 565 return(mbits); 566 } 567 568 int dztransitions, dzfasttimers; /*DEBUG*/ 569 dzscan() 570 { 571 register i; 572 register struct dzdevice *dzaddr; 573 register bit; 574 register struct tty *tp; 575 register car; 576 int olddzsilos = dzsilos; 577 int dztimer(); 578 579 for (i = 0; i < dz_cnt ; i++) { 580 dzaddr = dzpdma[i].p_addr; 581 if (dzaddr == 0) 582 continue; 583 tp = &dz_tty[i]; 584 bit = 1<<(i&07); 585 car = 0; 586 if (dzsoftCAR[i>>3]&bit) 587 car = 1; 588 else if (dzaddr->dzcsr & DZ_32) { 589 dzaddr->dzlcs = i&07; 590 dzwait(dzaddr); 591 car = dzaddr->dzlcs & DZ_CD; 592 } else 593 car = dzaddr->dzmsr&bit; 594 if (car) { 595 /* carrier present */ 596 if ((tp->t_state & TS_CARR_ON) == 0) 597 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 598 } else if ((tp->t_state&TS_CARR_ON) && 599 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) 600 dzaddr->dzdtr &= ~bit; 601 } 602 for (i = 0; i < NDZ; i++) { 603 ave(dzrate[i], dzchars[i], 8); 604 if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) { 605 dzpdma[i << 3].p_addr->dzcsr = DZ_IEN | DZ_SAE; 606 dzsilos |= (1 << i); 607 dztransitions++; /*DEBUG*/ 608 } else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) { 609 dzpdma[i << 3].p_addr->dzcsr = DZ_IEN; 610 dzsilos &= ~(1 << i); 611 } 612 dzchars[i] = 0; 613 } 614 if (dzsilos && !olddzsilos) 615 timeout(dztimer, (caddr_t)0, dztimerintvl); 616 timeout(dzscan, (caddr_t)0, hz); 617 } 618 619 dztimer() 620 { 621 register int dz; 622 register int s; 623 624 if (dzsilos == 0) 625 return; 626 s = spl5(); 627 dzfasttimers++; /*DEBUG*/ 628 for (dz = 0; dz < NDZ; dz++) 629 if (dzsilos & (1 << dz)) 630 dzrint(dz); 631 splx(s); 632 timeout(dztimer, (caddr_t) 0, dztimerintvl); 633 } 634 635 /* 636 * Reset state of driver if UBA reset was necessary. 637 * Reset parameters and restart transmission on open lines. 638 */ 639 dzreset(uban) 640 int uban; 641 { 642 register int unit; 643 register struct tty *tp; 644 register struct uba_device *ui; 645 646 for (unit = 0; unit < NDZLINE; unit++) { 647 ui = dzinfo[unit >> 3]; 648 if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 649 continue; 650 if (unit%8 == 0) 651 printf(" dz%d", unit>>3); 652 tp = &dz_tty[unit]; 653 if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 654 dzparam(unit); 655 (void) dzmctl(unit, DZ_ON, DMSET); 656 tp->t_state &= ~TS_BUSY; 657 dzstart(tp); 658 } 659 } 660 } 661 #endif 662