1 /* 2 * Copyright (c) 1982, 1986 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 * @(#)dh.c 7.14 (Berkeley) 06/28/90 7 */ 8 9 #include "dh.h" 10 #if NDH > 0 11 /* 12 * DH-11/DM-11 driver 13 */ 14 #include "machine/pte.h" 15 16 #include "uba.h" 17 #include "param.h" 18 #include "conf.h" 19 #include "user.h" 20 #include "proc.h" 21 #include "ioctl.h" 22 #include "tty.h" 23 #include "map.h" 24 #include "buf.h" 25 #include "vm.h" 26 #include "kernel.h" 27 #include "syslog.h" 28 29 #include "ubareg.h" 30 #include "ubavar.h" 31 #include "dhreg.h" 32 #include "dmreg.h" 33 34 #include "bkmac.h" 35 #include "clist.h" 36 #include "file.h" 37 #include "uio.h" 38 39 /* 40 * Definition of the driver for the auto-configuration program. 41 * There is one definition for the dh and one for the dm. 42 */ 43 int dhprobe(), dhattach(), dhrint(), dhxint(), dhtimer(); 44 struct uba_device *dhinfo[NDH]; 45 u_short dhstd[] = { 0 }; 46 struct uba_driver dhdriver = 47 { dhprobe, 0, dhattach, 0, dhstd, "dh", dhinfo }; 48 49 int dmprobe(), dmattach(), dmintr(); 50 struct uba_device *dminfo[NDH]; 51 u_short dmstd[] = { 0 }; 52 struct uba_driver dmdriver = 53 { dmprobe, 0, dmattach, 0, dmstd, "dm", dminfo }; 54 55 #ifndef PORTSELECTOR 56 #define ISPEED TTYDEF_SPEED 57 #define LFLAG TTYDEF_LFLAG 58 #else 59 #define ISPEED B4800 60 #define LFLAG (TTYDEF_LFLAG&~ECHO) 61 #endif 62 63 #define FASTTIMER (hz/30) /* scan rate with silos on */ 64 65 /* 66 * Local variables for the driver 67 */ 68 short dhsar[NDH]; /* software copy of last bar */ 69 short dhsoftCAR[NDH]; 70 71 struct tty dh11[NDH*16]; 72 int ndh11 = NDH*16; 73 int dhact; /* mask of active dh's */ 74 int dhsilos; /* mask of dh's with silo in use */ 75 int dhchars[NDH]; /* recent input count */ 76 int dhrate[NDH]; /* smoothed input count */ 77 int dhhighrate = 100; /* silo on if dhchars > dhhighrate */ 78 int dhlowrate = 75; /* silo off if dhrate < dhlowrate */ 79 static short timerstarted; 80 int dhstart(), ttrstrt(); 81 82 struct speedtab dhspeedtab[] = { 83 19200, 14, 84 9600, 13, 85 4800, 12, 86 2400, 11, 87 1800, 10, 88 1200, 9, 89 600, 8, 90 300, 7, 91 200, 6, 92 150, 5, 93 134, 4, 94 110, 3, 95 75, 2, 96 50, 1, 97 0, 0, 98 EXTA, 14, 99 EXTB, 15, 100 -1, -1 101 }; 102 103 /* 104 * The clist space is mapped by one terminal driver onto each UNIBUS. 105 * The identity of the board which allocated resources is recorded, 106 * so the process may be repeated after UNIBUS resets. 107 * The UBACVT macro converts a clist space address for unibus uban 108 * into an i/o space address for the DMA routine. 109 */ 110 int dh_uballoc[NUBA]; /* which dh (if any) allocated unibus map */ 111 int cbase[NUBA]; /* base address of clists in unibus map */ 112 #define UBACVT(x, uban) (cbase[uban] + ((x)-(char *)cfree)) 113 114 /* 115 * Routine for configuration to force a dh to interrupt. 116 * Set to transmit at 9600 baud, and cause a transmitter interrupt. 117 */ 118 /*ARGSUSED*/ 119 dhprobe(reg) 120 caddr_t reg; 121 { 122 register int br, cvec; /* these are ``value-result'' */ 123 register struct dhdevice *dhaddr = (struct dhdevice *)reg; 124 125 #ifdef lint 126 br = 0; cvec = br; br = cvec; 127 if (ndh11 == 0) ndh11 = 1; 128 dhrint(0); dhxint(0); 129 #endif 130 #ifndef notdef 131 dhaddr->un.dhcsr = DH_RIE|DH_MM|DH_RI; 132 DELAY(1000); 133 dhaddr->un.dhcsr &= ~DH_RI; 134 dhaddr->un.dhcsr = 0; 135 #else 136 dhaddr->un.dhcsr = DH_TIE; 137 DELAY(5); 138 dhaddr->dhlpr = (B9600 << 10) | (B9600 << 6) | BITS7|PENABLE; 139 dhaddr->dhbcr = -1; 140 dhaddr->dhcar = 0; 141 dhaddr->dhbar = 1; 142 DELAY(100000); /* wait 1/10'th of a sec for interrupt */ 143 dhaddr->un.dhcsr = 0; 144 if (cvec && cvec != 0x200) 145 cvec -= 4; /* transmit -> receive */ 146 #endif 147 return (sizeof (struct dhdevice)); 148 } 149 150 /* 151 * Routine called to attach a dh. 152 */ 153 dhattach(ui) 154 struct uba_device *ui; 155 { 156 157 dhsoftCAR[ui->ui_unit] = ui->ui_flags; 158 cbase[ui->ui_ubanum] = -1; 159 dh_uballoc[ui->ui_ubanum] = -1; 160 } 161 162 /* 163 * Configuration routine to cause a dm to interrupt. 164 */ 165 dmprobe(reg) 166 caddr_t reg; 167 { 168 register int br, vec; /* value-result */ 169 register struct dmdevice *dmaddr = (struct dmdevice *)reg; 170 171 #ifdef lint 172 br = 0; vec = br; br = vec; 173 dmintr(0); 174 #endif 175 dmaddr->dmcsr = DM_DONE|DM_IE; 176 DELAY(20); 177 dmaddr->dmcsr = 0; 178 return (1); 179 } 180 181 /*ARGSUSED*/ 182 dmattach(ui) 183 struct uba_device *ui; 184 { 185 186 /* no local state to set up */ 187 } 188 189 /* 190 * Open a DH11 line, mapping the clist onto the uba if this 191 * is the first dh on this uba. Turn on this dh if this is 192 * the first use of it. Also do a dmopen to wait for carrier. 193 */ 194 /*ARGSUSED*/ 195 dhopen(dev, flag) 196 dev_t dev; 197 { 198 register struct tty *tp; 199 register int unit, dh; 200 register struct dhdevice *addr; 201 register struct uba_device *ui; 202 int s, error; 203 int dhparam(); 204 205 unit = minor(dev); 206 dh = unit >> 4; 207 if (unit >= NDH*16 || (ui = dhinfo[dh])== 0 || ui->ui_alive == 0) 208 return (ENXIO); 209 tp = &dh11[unit]; 210 if (tp->t_state&TS_XCLUDE && u.u_uid!=0) 211 return (EBUSY); 212 addr = (struct dhdevice *)ui->ui_addr; 213 tp->t_addr = (caddr_t)addr; 214 tp->t_oproc = dhstart; 215 tp->t_param = dhparam; 216 tp->t_dev = dev; 217 /* 218 * While setting up state for this uba and this dh, 219 * block uba resets which can clear the state. 220 */ 221 s = spl5(); 222 if (cbase[ui->ui_ubanum] == -1) { 223 dh_uballoc[ui->ui_ubanum] = dh; 224 cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum, 225 (caddr_t)cfree, nclist*sizeof(struct cblock), 0)); 226 } 227 if (timerstarted == 0) { 228 timerstarted++; 229 timeout(dhtimer, (caddr_t) 0, hz); 230 } 231 if ((dhact&(1<<dh)) == 0) { 232 addr->un.dhcsr |= DH_IE; 233 dhact |= (1<<dh); 234 addr->dhsilo = 0; 235 } 236 splx(s); 237 /* 238 * If this is first open, initialize tty state to default. 239 */ 240 if ((tp->t_state&TS_ISOPEN) == 0) { 241 tp->t_state |= TS_WOPEN; 242 ttychars(tp); 243 #ifndef PORTSELECTOR 244 if (tp->t_ispeed == 0) { 245 #endif 246 tp->t_iflag = TTYDEF_IFLAG; 247 tp->t_oflag = TTYDEF_OFLAG; 248 tp->t_cflag = TTYDEF_CFLAG; 249 tp->t_lflag = LFLAG; 250 tp->t_ispeed = tp->t_ospeed = ISPEED; 251 #ifdef PORTSELECTOR 252 tp->t_cflag |= HUPCL; 253 #else 254 } 255 #endif 256 dhparam(tp, &tp->t_termios); 257 ttsetwater(tp); 258 } 259 /* 260 * Wait for carrier, then process line discipline specific open. 261 */ 262 if (error = dmopen(dev, flag)) 263 return (error); 264 return ((*linesw[tp->t_line].l_open)(dev, tp)); 265 } 266 267 /* 268 * Close a DH11 line, turning off the DM11. 269 */ 270 /*ARGSUSED*/ 271 dhclose(dev, flag) 272 dev_t dev; 273 int flag; 274 { 275 register struct tty *tp; 276 register unit; 277 278 unit = minor(dev); 279 tp = &dh11[unit]; 280 (*linesw[tp->t_line].l_close)(tp); 281 ((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017)); 282 if (tp->t_cflag&HUPCL || (tp->t_state&TS_ISOPEN)==0) 283 dmctl(unit, DML_OFF, DMSET); 284 return (ttyclose(tp)); 285 } 286 287 dhread(dev, uio, flag) 288 dev_t dev; 289 struct uio *uio; 290 { 291 register struct tty *tp = &dh11[minor(dev)]; 292 293 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 294 } 295 296 dhwrite(dev, uio, flag) 297 dev_t dev; 298 struct uio *uio; 299 { 300 register struct tty *tp = &dh11[minor(dev)]; 301 302 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 303 } 304 305 /* 306 * DH11 receiver interrupt. 307 */ 308 dhrint(dh) 309 int dh; 310 { 311 register struct tty *tp; 312 register c, cc; 313 register struct dhdevice *addr; 314 register struct tty *tp0; 315 register struct uba_device *ui; 316 int overrun = 0; 317 318 ui = dhinfo[dh]; 319 if (ui == 0 || ui->ui_alive == 0) 320 return; 321 addr = (struct dhdevice *)ui->ui_addr; 322 tp0 = &dh11[dh<<4]; 323 /* 324 * Loop fetching characters from the silo for this 325 * dh until there are no more in the silo. 326 */ 327 while ((c = addr->dhrcr) < 0) { 328 tp = tp0 + ((c>>8)&0xf); 329 dhchars[dh]++; 330 if ((tp->t_state&TS_ISOPEN)==0) { 331 wakeup((caddr_t)&tp->t_rawq); 332 #ifdef PORTSELECTOR 333 if ((tp->t_state&TS_WOPEN) == 0) 334 #endif 335 continue; 336 } 337 cc = c&0xff; 338 if (c&DH_PE) 339 cc |= TTY_PE; 340 if ((c&DH_DO) && overrun == 0) { 341 log(LOG_WARNING, "dh%d: silo overflow\n", dh); 342 overrun = 1; 343 } 344 if (c&DH_FE) 345 cc |= TTY_FE; 346 (*linesw[tp->t_line].l_rint)(cc, tp); 347 } 348 } 349 350 /* 351 * Ioctl for DH11. 352 */ 353 /*ARGSUSED*/ 354 dhioctl(dev, cmd, data, flag) 355 caddr_t data; 356 { 357 register struct tty *tp; 358 register int unit = minor(dev); 359 int error; 360 361 tp = &dh11[unit]; 362 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 363 if (error >= 0) 364 return (error); 365 error = ttioctl(tp, cmd, data, flag); 366 if (error >= 0) 367 return (error); 368 switch (cmd) { 369 370 case TIOCSBRK: 371 ((struct dhdevice *)(tp->t_addr))->dhbreak |= 1<<(unit&017); 372 break; 373 374 case TIOCCBRK: 375 ((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017)); 376 break; 377 378 case TIOCSDTR: 379 dmctl(unit, DML_DTR|DML_RTS, DMBIS); 380 break; 381 382 case TIOCCDTR: 383 dmctl(unit, DML_DTR|DML_RTS, DMBIC); 384 break; 385 386 default: 387 return (ENOTTY); 388 } 389 return (0); 390 } 391 392 /* 393 * Set parameters from open or stty into the DH hardware 394 * registers. 395 */ 396 dhparam(tp, t) 397 register struct tty *tp; 398 register struct termios *t; 399 { 400 register struct dhdevice *addr; 401 register int lpar; 402 register int cflag = t->c_cflag; 403 int unit = minor(tp->t_dev); 404 int s; 405 int ispeed = ttspeedtab(t->c_ispeed, dhspeedtab); 406 int ospeed = ttspeedtab(t->c_ospeed, dhspeedtab); 407 408 /* check requested parameters */ 409 if (ospeed < 0 || ispeed < 0 || (cflag&CSIZE) == CS5) 410 return(EINVAL); 411 if (ispeed == 0) 412 ispeed = ospeed; 413 /* and copy to tty */ 414 tp->t_ispeed = t->c_ispeed; 415 tp->t_ospeed = t->c_ospeed; 416 tp->t_cflag = cflag; 417 /* 418 * Block interrupts so parameters will be set 419 * before the line interrupts. 420 */ 421 addr = (struct dhdevice *)tp->t_addr; 422 s = spl5(); 423 addr->un.dhcsrl = (unit&0xf) | DH_IE; 424 if (ospeed == 0) { 425 tp->t_cflag |= HUPCL; 426 dmctl(unit, DML_OFF, DMSET); 427 splx(s); 428 return 0; 429 } 430 lpar = (ospeed<<10) | (ispeed<<6); 431 switch (cflag&CSIZE) { 432 case CS6: lpar |= BITS6; break; 433 case CS7: lpar |= BITS7; break; 434 case CS8: lpar |= BITS8; break; 435 } 436 if (cflag&PARENB) 437 lpar |= PENABLE; 438 if (cflag&PARODD) 439 lpar |= OPAR; 440 if (cflag&CSTOPB) 441 lpar |= TWOSB; 442 addr->dhlpr = lpar; 443 splx(s); 444 return 0; 445 } 446 447 /* 448 * DH11 transmitter interrupt. 449 * Restart each line which used to be active but has 450 * terminated transmission since the last interrupt. 451 */ 452 dhxint(dh) 453 int dh; 454 { 455 register struct tty *tp; 456 register struct dhdevice *addr; 457 short ttybit, bar, *sbar; 458 register struct uba_device *ui; 459 register int unit; 460 u_short cntr; 461 462 ui = dhinfo[dh]; 463 addr = (struct dhdevice *)ui->ui_addr; 464 if (addr->un.dhcsr & DH_NXM) { 465 addr->un.dhcsr |= DH_CNI; 466 printf("dh%d: NXM\n", dh); 467 } 468 sbar = &dhsar[dh]; 469 bar = *sbar & ~addr->dhbar; 470 unit = dh * 16; ttybit = 1; 471 addr->un.dhcsr &= (short)~DH_TI; 472 for (; bar; unit++, ttybit <<= 1) { 473 if (bar & ttybit) { 474 *sbar &= ~ttybit; 475 bar &= ~ttybit; 476 tp = &dh11[unit]; 477 tp->t_state &= ~TS_BUSY; 478 if (tp->t_state&TS_FLUSH) 479 tp->t_state &= ~TS_FLUSH; 480 else { 481 addr->un.dhcsrl = (unit&017)|DH_IE; 482 /* 483 * Do arithmetic in a short to make up 484 * for lost 16&17 bits. 485 */ 486 cntr = addr->dhcar - 487 UBACVT(tp->t_outq.c_cf, ui->ui_ubanum); 488 ndflush(&tp->t_outq, (int)cntr); 489 } 490 if (tp->t_line) 491 (*linesw[tp->t_line].l_start)(tp); 492 else 493 dhstart(tp); 494 } 495 } 496 } 497 498 /* 499 * Start (restart) transmission on the given DH11 line. 500 */ 501 dhstart(tp) 502 register struct tty *tp; 503 { 504 register struct dhdevice *addr; 505 register int car, dh, unit, nch; 506 int s; 507 508 unit = minor(tp->t_dev); 509 dh = unit >> 4; 510 unit &= 0xf; 511 addr = (struct dhdevice *)tp->t_addr; 512 513 /* 514 * Must hold interrupts in following code to prevent 515 * state of the tp from changing. 516 */ 517 s = spl5(); 518 /* 519 * If it's currently active, or delaying, no need to do anything. 520 */ 521 if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 522 goto out; 523 /* 524 * If there are sleepers, and output has drained below low 525 * water mark, wake up the sleepers. 526 */ 527 if (tp->t_outq.c_cc<=tp->t_lowat) { 528 if (tp->t_state&TS_ASLEEP) { 529 tp->t_state &= ~TS_ASLEEP; 530 wakeup((caddr_t)&tp->t_outq); 531 } 532 if (tp->t_wsel) { 533 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 534 tp->t_wsel = 0; 535 tp->t_state &= ~TS_WCOLL; 536 } 537 } 538 /* 539 * Now restart transmission unless the output queue is 540 * empty. 541 */ 542 if (tp->t_outq.c_cc == 0) 543 goto out; 544 if (1 || !(tp->t_oflag&OPOST)) /*XXX*/ 545 nch = ndqb(&tp->t_outq, 0); 546 else { 547 nch = ndqb(&tp->t_outq, 0200); 548 /* 549 * If first thing on queue is a delay process it. 550 */ 551 if (nch == 0) { 552 nch = getc(&tp->t_outq); 553 timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6); 554 tp->t_state |= TS_TIMEOUT; 555 goto out; 556 } 557 } 558 /* 559 * If characters to transmit, restart transmission. 560 */ 561 if (nch) { 562 car = UBACVT(tp->t_outq.c_cf, dhinfo[dh]->ui_ubanum); 563 addr->un.dhcsrl = unit|((car>>12)&0x30)|DH_IE; 564 /* 565 * The following nonsense with short word 566 * is to make sure the dhbar |= word below 567 * is done with an interlocking bisw2 instruction. 568 */ 569 { short word = 1 << unit; 570 dhsar[dh] |= word; 571 addr->dhcar = car; 572 addr->dhbcr = -nch; 573 addr->dhbar |= word; 574 } 575 tp->t_state |= TS_BUSY; 576 } 577 out: 578 splx(s); 579 } 580 581 /* 582 * Stop output on a line, e.g. for ^S/^Q or output flush. 583 */ 584 /*ARGSUSED*/ 585 dhstop(tp, flag) 586 register struct tty *tp; 587 { 588 register struct dhdevice *addr; 589 register int unit, s; 590 591 addr = (struct dhdevice *)tp->t_addr; 592 /* 593 * Block input/output interrupts while messing with state. 594 */ 595 s = spl5(); 596 if (tp->t_state & TS_BUSY) { 597 /* 598 * Device is transmitting; stop output 599 * by selecting the line and setting the byte 600 * count to -1. We will clean up later 601 * by examining the address where the dh stopped. 602 */ 603 unit = minor(tp->t_dev); 604 addr->un.dhcsrl = (unit&017) | DH_IE; 605 if ((tp->t_state&TS_TTSTOP)==0) 606 tp->t_state |= TS_FLUSH; 607 addr->dhbcr = -1; 608 } 609 splx(s); 610 } 611 612 /* 613 * Reset state of driver if UBA reset was necessary. 614 * Reset the csrl and lpr registers on open lines, and 615 * restart transmitters. 616 */ 617 dhreset(uban) 618 int uban; 619 { 620 register int dh, unit; 621 register struct tty *tp; 622 register struct uba_device *ui; 623 int i; 624 625 dh = 0; 626 for (dh = 0; dh < NDH; dh++) { 627 ui = dhinfo[dh]; 628 if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 629 continue; 630 printf(" dh%d", dh); 631 if (dh_uballoc[uban] == dh) { 632 int info; 633 634 info = uballoc(uban, (caddr_t)cfree, 635 nclist * sizeof(struct cblock), UBA_CANTWAIT); 636 if (info) 637 cbase[uban] = UBAI_ADDR(info); 638 else { 639 printf(" [can't get uba map]"); 640 cbase[uban] = -1; 641 } 642 } 643 ((struct dhdevice *)ui->ui_addr)->un.dhcsr |= DH_IE; 644 ((struct dhdevice *)ui->ui_addr)->dhsilo = 0; 645 unit = dh * 16; 646 for (i = 0; i < 16; i++) { 647 tp = &dh11[unit]; 648 if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 649 dhparam(unit); 650 dmctl(unit, DML_ON, DMSET); 651 tp->t_state &= ~TS_BUSY; 652 dhstart(tp); 653 } 654 unit++; 655 } 656 } 657 dhsilos = 0; 658 } 659 660 int dhtransitions, dhslowtimers, dhfasttimers; /*DEBUG*/ 661 /* 662 * At software clock interrupt time, check status. 663 * Empty all the dh silos that are in use, and decide whether 664 * to turn any silos off or on. 665 */ 666 dhtimer() 667 { 668 register int dh, s; 669 static int timercalls; 670 671 if (dhsilos) { 672 dhfasttimers++; /*DEBUG*/ 673 timercalls++; 674 s = spl5(); 675 for (dh = 0; dh < NDH; dh++) 676 if (dhsilos & (1 << dh)) 677 dhrint(dh); 678 splx(s); 679 } 680 if ((dhsilos == 0) || ((timercalls += FASTTIMER) >= hz)) { 681 dhslowtimers++; /*DEBUG*/ 682 timercalls = 0; 683 for (dh = 0; dh < NDH; dh++) { 684 ave(dhrate[dh], dhchars[dh], 8); 685 if ((dhchars[dh] > dhhighrate) && 686 ((dhsilos & (1 << dh)) == 0)) { 687 ((struct dhdevice *)(dhinfo[dh]->ui_addr))->dhsilo = 688 (dhchars[dh] > 500? 32 : 16); 689 dhsilos |= (1 << dh); 690 dhtransitions++; /*DEBUG*/ 691 } else if ((dhsilos & (1 << dh)) && 692 (dhrate[dh] < dhlowrate)) { 693 ((struct dhdevice *)(dhinfo[dh]->ui_addr))->dhsilo = 0; 694 dhsilos &= ~(1 << dh); 695 } 696 dhchars[dh] = 0; 697 } 698 } 699 timeout(dhtimer, (caddr_t) 0, dhsilos? FASTTIMER: hz); 700 } 701 702 /* 703 * Turn on the line associated with dh dev. 704 */ 705 dmopen(dev, flag) 706 dev_t dev; 707 { 708 register struct tty *tp; 709 register struct dmdevice *addr; 710 register struct uba_device *ui; 711 register int unit; 712 register int dm; 713 int s, error = 0; 714 715 unit = minor(dev); 716 dm = unit >> 4; 717 tp = &dh11[unit]; 718 unit &= 0xf; 719 if (dm >= NDH || (ui = dminfo[dm]) == 0 || ui->ui_alive == 0) { 720 tp->t_state |= TS_CARR_ON; 721 return (0); 722 } 723 addr = (struct dmdevice *)ui->ui_addr; 724 s = spl5(); 725 for (;;) { 726 tp->t_state |= TS_WOPEN; 727 addr->dmcsr &= ~DM_SE; 728 while (addr->dmcsr & DM_BUSY) 729 ; 730 addr->dmcsr = unit; 731 addr->dmlstat = DML_ON; 732 if ((addr->dmlstat & DML_CAR) || (dhsoftCAR[dm] & (1 << unit))) 733 tp->t_state |= TS_CARR_ON; 734 addr->dmcsr = DM_IE|DM_SE; 735 if (tp->t_state&TS_CARR_ON || flag&O_NONBLOCK || 736 tp->t_cflag&CLOCAL) 737 break; 738 if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 739 ttopen, 0)) 740 break; 741 } 742 splx(s); 743 return (error); 744 } 745 746 /* 747 * Dump control bits into the DM registers. 748 */ 749 dmctl(dev, bits, how) 750 dev_t dev; 751 int bits, how; 752 { 753 register struct uba_device *ui; 754 register struct dmdevice *addr; 755 register int unit, s; 756 int dm; 757 758 unit = minor(dev); 759 dm = unit >> 4; 760 if ((ui = dminfo[dm]) == 0 || ui->ui_alive == 0) 761 return; 762 addr = (struct dmdevice *)ui->ui_addr; 763 s = spl5(); 764 addr->dmcsr &= ~DM_SE; 765 while (addr->dmcsr & DM_BUSY) 766 ; 767 addr->dmcsr = unit & 0xf; 768 switch(how) { 769 case DMSET: 770 addr->dmlstat = bits; 771 break; 772 case DMBIS: 773 addr->dmlstat |= bits; 774 break; 775 case DMBIC: 776 addr->dmlstat &= ~bits; 777 break; 778 } 779 addr->dmcsr = DM_IE|DM_SE; 780 splx(s); 781 } 782 783 /* 784 * DM11 interrupt; deal with carrier transitions. 785 */ 786 dmintr(dm) 787 register int dm; 788 { 789 register struct uba_device *ui; 790 register struct tty *tp; 791 register struct dmdevice *addr; 792 int unit; 793 794 ui = dminfo[dm]; 795 if (ui == 0) 796 return; 797 addr = (struct dmdevice *)ui->ui_addr; 798 if (addr->dmcsr&DM_DONE) { 799 if (addr->dmcsr&DM_CF) { 800 unit = addr->dmcsr & 0xf; 801 tp = &dh11[(dm << 4) + unit]; 802 if (addr->dmlstat & DML_CAR) 803 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 804 else if ((dhsoftCAR[dm] & (1<<unit)) == 0 && 805 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) 806 addr->dmlstat = 0; 807 } 808 addr->dmcsr = DM_IE|DM_SE; 809 } 810 } 811 #endif 812