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