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