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