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