1 /* dh.c 4.37 81/07/10 */ 2 3 #include "dh.h" 4 #if NDH > 0 5 /* 6 * DH-11/DM-11 driver 7 */ 8 #include "bk.h" 9 #include "../h/param.h" 10 #include "../h/conf.h" 11 #include "../h/dir.h" 12 #include "../h/user.h" 13 #include "../h/tty.h" 14 #include "../h/map.h" 15 #include "../h/pte.h" 16 #include "../h/buf.h" 17 #include "../h/vm.h" 18 #include "../h/ubareg.h" 19 #include "../h/ubavar.h" 20 #include "../h/bk.h" 21 #include "../h/clist.h" 22 #include "../h/mx.h" 23 #include "../h/file.h" 24 25 /* 26 * Definition of the driver for the auto-configuration program. 27 * There is one definition for the dh and one for the dm. 28 */ 29 int dhprobe(), dhattach(), dhrint(), dhxint(); 30 struct uba_device *dhinfo[NDH]; 31 u_short dhstd[] = { 0 }; 32 struct uba_driver dhdriver = 33 { dhprobe, 0, dhattach, 0, dhstd, "dh", dhinfo }; 34 35 int dmprobe(), dmattach(), dmintr(); 36 struct uba_device *dminfo[NDH]; 37 u_short dmstd[] = { 0 }; 38 struct uba_driver dmdriver = 39 { dmprobe, 0, dmattach, 0, dmstd, "dm", dminfo }; 40 41 struct dhdevice 42 { 43 union { 44 short dhcsr; /* control-status register */ 45 char dhcsrl; /* low byte for line select */ 46 } un; 47 short dhrcr; /* receive character register */ 48 short dhlpr; /* line parameter register */ 49 u_short dhcar; /* current address register */ 50 short dhbcr; /* byte count register */ 51 u_short dhbar; /* buffer active register */ 52 short dhbreak; /* break control register */ 53 short dhsilo; /* silo status register */ 54 }; 55 56 /* Bits in dhcsr */ 57 #define DH_TI 0100000 /* transmit interrupt */ 58 #define DH_SI 0040000 /* storage interrupt */ 59 #define DH_TIE 0020000 /* transmit interrupt enable */ 60 #define DH_SIE 0010000 /* storage interrupt enable */ 61 #define DH_MC 0004000 /* master clear */ 62 #define DH_NXM 0002000 /* non-existant memory */ 63 #define DH_MM 0001000 /* maintenance mode */ 64 #define DH_CNI 0000400 /* clear non-existant memory interrupt */ 65 #define DH_RI 0000200 /* receiver interrupt */ 66 #define DH_RIE 0000100 /* receiver interrupt enable */ 67 68 /* Bits in dhlpr */ 69 #define BITS6 01 70 #define BITS7 02 71 #define BITS8 03 72 #define TWOSB 04 73 #define PENABLE 020 74 /* DEC manuals incorrectly say this bit causes generation of even parity. */ 75 #define OPAR 040 76 #define HDUPLX 040000 77 78 #if NBK == 0 79 #define DH_IE (DH_TIE|DH_RIE) 80 #else 81 #define DH_IE (DH_TIE|DH_SIE|DH_RIE) 82 #endif 83 84 /* Bits in dhrcr */ 85 #define DH_PE 0010000 /* parity error */ 86 #define DH_FE 0020000 /* framing error */ 87 #define DH_DO 0040000 /* data overrun */ 88 89 struct dmdevice 90 { 91 short dmcsr; /* control status register */ 92 short dmlstat; /* line status register */ 93 short dmpad1[2]; 94 }; 95 96 /* bits in dm csr */ 97 #define DM_RF 0100000 /* ring flag */ 98 #define DM_CF 0040000 /* carrier flag */ 99 #define DM_CTS 0020000 /* clear to send */ 100 #define DM_SRF 0010000 /* secondary receive flag */ 101 #define DM_CS 0004000 /* clear scan */ 102 #define DM_CM 0002000 /* clear multiplexor */ 103 #define DM_MM 0001000 /* maintenance mode */ 104 #define DM_STP 0000400 /* step */ 105 #define DM_DONE 0000200 /* scanner is done */ 106 #define DM_IE 0000100 /* interrupt enable */ 107 #define DM_SE 0000040 /* scan enable */ 108 #define DM_BUSY 0000020 /* scan busy */ 109 110 /* bits in dm lsr */ 111 #define DML_RNG 0000200 /* ring */ 112 #define DML_CAR 0000100 /* carrier detect */ 113 #define DML_CTS 0000040 /* clear to send */ 114 #define DML_SR 0000020 /* secondary receive */ 115 #define DML_ST 0000010 /* secondary transmit */ 116 #define DML_RTS 0000004 /* request to send */ 117 #define DML_DTR 0000002 /* data terminal ready */ 118 #define DML_LE 0000001 /* line enable */ 119 120 #define DML_ON (DML_DTR|DML_RTS|DML_LE) 121 #define DML_OFF (DML_LE) 122 123 /* 124 * Local variables for the driver 125 */ 126 short dhsar[NDH]; /* software copy of last bar */ 127 short dhsoftCAR[NDH]; 128 129 struct tty dh11[NDH*16]; 130 int ndh11 = NDH*16; 131 int dhact; /* mask of active dh's */ 132 int dhstart(), ttrstrt(); 133 134 /* 135 * The clist space is mapped by the driver onto each UNIBUS. 136 * The UBACVT macro converts a clist space address for unibus uban 137 * into an i/o space address for the DMA routine. 138 */ 139 int dh_ubinfo[MAXNUBA]; /* info about allocated unibus map */ 140 int cbase[MAXNUBA]; /* base address in unibus map */ 141 #define UBACVT(x, uban) (cbase[uban] + ((x)-(char *)cfree)) 142 143 /* 144 * Routine for configuration to force a dh to interrupt. 145 * Set to transmit at 9600 baud, and cause a transmitter interrupt. 146 */ 147 /*ARGSUSED*/ 148 dhprobe(reg) 149 caddr_t reg; 150 { 151 register int br, cvec; /* these are ``value-result'' */ 152 register struct dhdevice *dhaddr = (struct dhdevice *)reg; 153 154 #ifdef lint 155 br = 0; cvec = br; br = cvec; 156 #endif 157 #ifndef notdef 158 dhaddr->un.dhcsr = DH_RIE|DH_MM|DH_RI; 159 DELAY(25); 160 dhaddr->un.dhcsr = 0; 161 #else 162 dhaddr->un.dhcsr = DH_TIE; 163 DELAY(5); 164 dhaddr->dhlpr = (B9600 << 10) | (B9600 << 6) | BITS7|PENABLE; 165 dhaddr->dhbcr = -1; 166 dhaddr->dhcar = 0; 167 dhaddr->dhbar = 1; 168 DELAY(100000); /* wait 1/10'th of a sec for interrupt */ 169 dhaddr->un.dhcsr = 0; 170 if (cvec && cvec != 0x200) 171 cvec -= 4; /* transmit -> receive */ 172 #endif 173 return (1); 174 } 175 176 /* 177 * Routine called to attach a dh. 178 */ 179 dhattach(ui) 180 struct uba_device *ui; 181 { 182 183 dhsoftCAR[ui->ui_unit] = ui->ui_flags; 184 } 185 186 /* 187 * Configuration routine to cause a dm to interrupt. 188 */ 189 dmprobe(reg) 190 caddr_t reg; 191 { 192 register int br, vec; /* value-result */ 193 register struct dmdevice *dmaddr = (struct dmdevice *)reg; 194 195 #ifdef lint 196 br = 0; vec = br; br = vec; 197 #endif 198 dmaddr->dmcsr = DM_DONE|DM_IE; 199 DELAY(20); 200 dmaddr->dmcsr = 0; 201 return (1); 202 } 203 204 /*ARGSUSED*/ 205 dmattach(ui) 206 struct uba_device *ui; 207 { 208 209 /* no local state to set up */ 210 } 211 212 /* 213 * Open a DH11 line, mapping the clist onto the uba if this 214 * is the first dh on this uba. Turn on this dh if this is 215 * the first use of it. Also do a dmopen to wait for carrier. 216 */ 217 /*ARGSUSED*/ 218 dhopen(dev, flag) 219 dev_t dev; 220 { 221 register struct tty *tp; 222 register int unit, dh; 223 register struct dhdevice *addr; 224 register struct uba_device *ui; 225 int s; 226 227 unit = minor(dev); 228 dh = unit >> 4; 229 if (unit >= NDH*16 || (ui = dhinfo[dh])== 0 || ui->ui_alive == 0) { 230 u.u_error = ENXIO; 231 return; 232 } 233 tp = &dh11[unit]; 234 if (tp->t_state&XCLUDE && u.u_uid!=0) { 235 u.u_error = EBUSY; 236 return; 237 } 238 addr = (struct dhdevice *)ui->ui_addr; 239 tp->t_addr = (caddr_t)addr; 240 tp->t_oproc = dhstart; 241 tp->t_iproc = NULL; 242 tp->t_state |= WOPEN; 243 /* 244 * While setting up state for this uba and this dh, 245 * block uba resets which can clear the state. 246 */ 247 s = spl5(); 248 if (dh_ubinfo[ui->ui_ubanum] == 0) { 249 /* 512+ is a kludge to try to get around a hardware problem */ 250 dh_ubinfo[ui->ui_ubanum] = 251 uballoc(ui->ui_ubanum, (caddr_t)cfree, 252 512+nclist*sizeof(struct cblock), 0); 253 cbase[ui->ui_ubanum] = dh_ubinfo[ui->ui_ubanum]&0x3ffff; 254 } 255 if ((dhact&(1<<dh)) == 0) { 256 addr->un.dhcsr |= DH_IE; 257 dhact |= (1<<dh); 258 #if NBK > 0 259 addr->dhsilo = 16; 260 #endif 261 } 262 splx(s); 263 /* 264 * If this is first open, initialze tty state to default. 265 */ 266 if ((tp->t_state&ISOPEN) == 0) { 267 ttychars(tp); 268 if (tp->t_ispeed == 0) { 269 tp->t_ispeed = B300; 270 tp->t_ospeed = B300; 271 tp->t_flags = ODDP|EVENP|ECHO; 272 } 273 dhparam(unit); 274 } 275 /* 276 * Wait for carrier, then process line discipline specific open. 277 */ 278 dmopen(dev); 279 (*linesw[tp->t_line].l_open)(dev, tp); 280 } 281 282 /* 283 * Close a DH11 line, turning off the DM11. 284 */ 285 /*ARGSUSED*/ 286 dhclose(dev, flag) 287 dev_t dev; 288 int flag; 289 { 290 register struct tty *tp; 291 register unit; 292 293 unit = minor(dev); 294 tp = &dh11[unit]; 295 (*linesw[tp->t_line].l_close)(tp); 296 ((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017)); 297 if (tp->t_state&HUPCLS || (tp->t_state&ISOPEN)==0) 298 dmctl(unit, DML_OFF, DMSET); 299 ttyclose(tp); 300 } 301 302 dhread(dev) 303 dev_t dev; 304 { 305 register struct tty *tp; 306 307 tp = &dh11[minor(dev)]; 308 (*linesw[tp->t_line].l_read)(tp); 309 } 310 311 dhwrite(dev) 312 dev_t dev; 313 { 314 register struct tty *tp; 315 316 tp = &dh11[minor(dev)]; 317 (*linesw[tp->t_line].l_write)(tp); 318 } 319 320 /* 321 * DH11 receiver interrupt. 322 */ 323 dhrint(dh) 324 int dh; 325 { 326 register struct tty *tp; 327 register c; 328 register struct dhdevice *addr; 329 register struct tty *tp0; 330 register struct uba_device *ui; 331 int overrun = 0; 332 333 ui = dhinfo[dh]; 334 if (ui == 0 || ui->ui_alive == 0) 335 return; 336 addr = (struct dhdevice *)ui->ui_addr; 337 tp0 = &dh11[dh<<4]; 338 /* 339 * Loop fetching characters from the silo for this 340 * dh until there are no more in the silo. 341 */ 342 while ((c = addr->dhrcr) < 0) { 343 tp = tp0 + ((c>>8)&0xf); 344 if ((tp->t_state&ISOPEN)==0) { 345 wakeup((caddr_t)tp); 346 continue; 347 } 348 if (c & DH_PE) 349 if ((tp->t_flags&(EVENP|ODDP))==EVENP 350 || (tp->t_flags&(EVENP|ODDP))==ODDP ) 351 continue; 352 if ((c & DH_DO) && overrun == 0) { 353 printf("dh%d: silo overflow\n", dh); 354 overrun = 1; 355 } 356 if (c & DH_FE) 357 /* 358 * At framing error (break) generate 359 * a null (in raw mode, for getty), or a 360 * interrupt (in cooked/cbreak mode). 361 */ 362 if (tp->t_flags&RAW) 363 c = 0; 364 else 365 c = tun.t_intrc; 366 #if NBK > 0 367 if (tp->t_line == NETLDISC) { 368 c &= 0177; 369 BKINPUT(c, tp); 370 } else 371 #endif 372 (*linesw[tp->t_line].l_rint)(c, tp); 373 } 374 } 375 376 /* 377 * Ioctl for DH11. 378 */ 379 /*ARGSUSED*/ 380 dhioctl(dev, cmd, addr, flag) 381 caddr_t addr; 382 { 383 register struct tty *tp; 384 register unit = minor(dev); 385 386 tp = &dh11[unit]; 387 cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 388 if (cmd == 0) 389 return; 390 if (ttioctl(tp, cmd, addr, flag)) { 391 if (cmd==TIOCSETP || cmd==TIOCSETN) 392 dhparam(unit); 393 } else switch(cmd) { 394 case TIOCSBRK: 395 ((struct dhdevice *)(tp->t_addr))->dhbreak |= 1<<(unit&017); 396 break; 397 case TIOCCBRK: 398 ((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017)); 399 break; 400 case TIOCSDTR: 401 dmctl(unit, DML_DTR|DML_RTS, DMBIS); 402 break; 403 case TIOCCDTR: 404 dmctl(unit, DML_DTR|DML_RTS, DMBIC); 405 break; 406 default: 407 u.u_error = ENOTTY; 408 } 409 } 410 411 /* 412 * Set parameters from open or stty into the DH hardware 413 * registers. 414 */ 415 dhparam(unit) 416 register int unit; 417 { 418 register struct tty *tp; 419 register struct dhdevice *addr; 420 register int lpar; 421 int s; 422 423 tp = &dh11[unit]; 424 addr = (struct dhdevice *)tp->t_addr; 425 /* 426 * Block interrupts so parameters will be set 427 * before the line interrupts. 428 */ 429 s = spl5(); 430 addr->un.dhcsrl = (unit&0xf) | DH_IE; 431 if ((tp->t_ispeed)==0) { 432 tp->t_state |= HUPCLS; 433 dmctl(unit, DML_OFF, DMSET); 434 return; 435 } 436 lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6); 437 if ((tp->t_ispeed) == B134) 438 lpar |= BITS6|PENABLE|HDUPLX; 439 else if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT)) 440 lpar |= BITS8; 441 else 442 lpar |= BITS7|PENABLE; 443 if ((tp->t_flags&EVENP) == 0) 444 lpar |= OPAR; 445 if ((tp->t_ospeed) == B110) 446 lpar |= TWOSB; 447 addr->dhlpr = lpar; 448 splx(s); 449 } 450 451 /* 452 * DH11 transmitter interrupt. 453 * Restart each line which used to be active but has 454 * terminated transmission since the last interrupt. 455 */ 456 dhxint(dh) 457 int dh; 458 { 459 register struct tty *tp; 460 register struct dhdevice *addr; 461 short ttybit, bar, *sbar; 462 register struct uba_device *ui; 463 register int unit; 464 u_short cntr; 465 466 ui = dhinfo[dh]; 467 addr = (struct dhdevice *)ui->ui_addr; 468 if (addr->un.dhcsr & DH_NXM) { 469 addr->un.dhcsr |= DH_CNI; 470 printf("dh%d: NXM\n", dh); 471 } 472 sbar = &dhsar[dh]; 473 bar = *sbar & ~addr->dhbar; 474 unit = dh * 16; ttybit = 1; 475 addr->un.dhcsr &= (short)~DH_TI; 476 for (; bar; unit++, ttybit <<= 1) { 477 if (bar & ttybit) { 478 *sbar &= ~ttybit; 479 bar &= ~ttybit; 480 tp = &dh11[unit]; 481 tp->t_state &= ~BUSY; 482 if (tp->t_state&FLUSH) 483 tp->t_state &= ~FLUSH; 484 else { 485 addr->un.dhcsrl = (unit&017)|DH_IE; 486 /* 487 * Do arithmetic in a short to make up 488 * for lost 16&17 bits. 489 */ 490 cntr = addr->dhcar - 491 UBACVT(tp->t_outq.c_cf, ui->ui_ubanum); 492 ndflush(&tp->t_outq, (int)cntr); 493 } 494 if (tp->t_line) 495 (*linesw[tp->t_line].l_start)(tp); 496 else 497 dhstart(tp); 498 } 499 } 500 } 501 502 /* 503 * Start (restart) transmission on the given DH11 line. 504 */ 505 dhstart(tp) 506 register struct tty *tp; 507 { 508 register struct dhdevice *addr; 509 register int car, dh, unit, nch; 510 int s; 511 512 unit = minor(tp->t_dev); 513 dh = unit >> 4; 514 unit &= 0xf; 515 addr = (struct dhdevice *)tp->t_addr; 516 517 /* 518 * Must hold interrupts in following code to prevent 519 * state of the tp from changing. 520 */ 521 s = spl5(); 522 /* 523 * If it's currently active, or delaying, no need to do anything. 524 */ 525 if (tp->t_state&(TIMEOUT|BUSY|TTSTOP)) 526 goto out; 527 /* 528 * If there are sleepers, and output has drained below low 529 * water mark, wake up the sleepers. 530 */ 531 if ((tp->t_state&ASLEEP) && tp->t_outq.c_cc<=TTLOWAT(tp)) { 532 tp->t_state &= ~ASLEEP; 533 if (tp->t_chan) 534 mcstart(tp->t_chan, (caddr_t)&tp->t_outq); 535 else 536 wakeup((caddr_t)&tp->t_outq); 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 (tp->t_flags&RAW || tp->t_local&LLITOUT) 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 |= 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 |= 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 & 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&TTSTOP)==0) 606 tp->t_state |= 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 if (dh_ubinfo[uban] == 0) 626 return; 627 ubarelse(uban, &dh_ubinfo[uban]); 628 dh_ubinfo[uban] = uballoc(uban, (caddr_t)cfree, 629 512+nclist*sizeof (struct cblock), 0); 630 cbase[uban] = dh_ubinfo[uban]&0x3ffff; 631 dh = 0; 632 for (dh = 0; dh < NDH; dh++) { 633 ui = dhinfo[dh]; 634 if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 635 continue; 636 printf(" dh%d", dh); 637 ((struct dhdevice *)ui->ui_addr)->un.dhcsr |= DH_IE; 638 #if NBK > 0 639 ((struct dhdevice *)ui->ui_addr)->dhsilo = 16; 640 #endif 641 unit = dh * 16; 642 for (i = 0; i < 16; i++) { 643 tp = &dh11[unit]; 644 if (tp->t_state & (ISOPEN|WOPEN)) { 645 dhparam(unit); 646 dmctl(unit, DML_ON, DMSET); 647 tp->t_state &= ~BUSY; 648 dhstart(tp); 649 } 650 unit++; 651 } 652 } 653 dhtimer(); 654 } 655 656 /* 657 * At software clock interrupt time or after a UNIBUS reset 658 * empty all the dh silos. 659 */ 660 dhtimer() 661 { 662 register int dh; 663 664 for (dh = 0; dh < NDH; dh++) 665 dhrint(dh); 666 } 667 668 /* 669 * Turn on the line associated with dh dev. 670 */ 671 dmopen(dev) 672 dev_t dev; 673 { 674 register struct tty *tp; 675 register struct dmdevice *addr; 676 register struct uba_device *ui; 677 register int unit; 678 register int dm; 679 int s; 680 681 unit = minor(dev); 682 dm = unit >> 4; 683 tp = &dh11[unit]; 684 unit &= 0xf; 685 if (dm >= NDH || (ui = dminfo[dm]) == 0 || ui->ui_alive == 0 || 686 (dhsoftCAR[dm]&(1<<unit))) { 687 tp->t_state |= CARR_ON; 688 return; 689 } 690 addr = (struct dmdevice *)ui->ui_addr; 691 s = spl5(); 692 addr->dmcsr &= ~DM_SE; 693 while (addr->dmcsr & DM_BUSY) 694 ; 695 addr->dmcsr = unit; 696 addr->dmlstat = DML_ON; 697 if (addr->dmlstat&DML_CAR) 698 tp->t_state |= CARR_ON; 699 addr->dmcsr = DM_IE|DM_SE; 700 while ((tp->t_state&CARR_ON)==0) 701 sleep((caddr_t)&tp->t_rawq, TTIPRI); 702 splx(s); 703 } 704 705 /* 706 * Dump control bits into the DM registers. 707 */ 708 dmctl(dev, bits, how) 709 dev_t dev; 710 int bits, how; 711 { 712 register struct uba_device *ui; 713 register struct dmdevice *addr; 714 register int unit, s; 715 int dm; 716 717 unit = minor(dev); 718 dm = unit >> 4; 719 if ((ui = dminfo[dm]) == 0 || ui->ui_alive == 0) 720 return; 721 addr = (struct dmdevice *)ui->ui_addr; 722 s = spl5(); 723 addr->dmcsr &= ~DM_SE; 724 while (addr->dmcsr & DM_BUSY) 725 ; 726 addr->dmcsr = unit & 0xf; 727 switch(how) { 728 case DMSET: 729 addr->dmlstat = bits; 730 break; 731 case DMBIS: 732 addr->dmlstat |= bits; 733 break; 734 case DMBIC: 735 addr->dmlstat &= ~bits; 736 break; 737 } 738 addr->dmcsr = DM_IE|DM_SE; 739 splx(s); 740 } 741 742 /* 743 * DM11 interrupt; deal with carrier transitions. 744 */ 745 dmintr(dm) 746 register int dm; 747 { 748 register struct uba_device *ui; 749 register struct tty *tp; 750 register struct dmdevice *addr; 751 752 ui = dminfo[dm]; 753 if (ui == 0) 754 return; 755 addr = (struct dmdevice *)ui->ui_addr; 756 if (addr->dmcsr&DM_DONE) { 757 if (addr->dmcsr&DM_CF) { 758 tp = &dh11[(dm<<4)+(addr->dmcsr&0xf)]; 759 wakeup((caddr_t)&tp->t_rawq); 760 if ((tp->t_state&WOPEN)==0 && 761 (tp->t_local&LMDMBUF)) { 762 if (addr->dmlstat & DML_CAR) { 763 tp->t_state &= ~TTSTOP; 764 ttstart(tp); 765 } else if ((tp->t_state&TTSTOP) == 0) { 766 tp->t_state |= TTSTOP; 767 dhstop(tp, 0); 768 } 769 } else if ((addr->dmlstat&DML_CAR)==0) { 770 if ((tp->t_state&WOPEN)==0 && 771 (tp->t_local&LNOHANG)==0) { 772 gsignal(tp->t_pgrp, SIGHUP); 773 gsignal(tp->t_pgrp, SIGCONT); 774 addr->dmlstat = 0; 775 flushtty(tp, FREAD|FWRITE); 776 } 777 tp->t_state &= ~CARR_ON; 778 } else 779 tp->t_state |= CARR_ON; 780 } 781 addr->dmcsr = DM_IE|DM_SE; 782 } 783 } 784 #endif 785