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