1 /* dmf.c 4.16 82/12/17 */ 2 3 #include "dmf.h" 4 #if NDMF > 0 5 /* 6 * DMF32 driver 7 * 8 * TODO: 9 * test with modem 10 * load as much as possible into silo 11 * get correct numbers for receive silo parameter timeout 12 * use auto XON/XOFF 13 * test reset code 14 * test with more than one unit 15 * optimize for efficient DMA and dynamically 16 * decide between silo and DMA mode 17 */ 18 #include "../machine/pte.h" 19 20 #include "bk.h" 21 #include "../h/param.h" 22 #include "../h/conf.h" 23 #include "../h/dir.h" 24 #include "../h/user.h" 25 #include "../h/ioctl.h" 26 #include "../h/tty.h" 27 #include "../h/map.h" 28 #include "../h/buf.h" 29 #include "../h/vm.h" 30 #include "../h/bk.h" 31 #include "../h/clist.h" 32 #include "../h/file.h" 33 #include "../h/uio.h" 34 35 #include "../vaxuba/ubareg.h" 36 #include "../vaxuba/ubavar.h" 37 38 /* 39 * Definition of the driver for the auto-configuration program. 40 */ 41 int dmfprobe(), dmfattach(), dmfrint(), dmfxint(); 42 struct uba_device *dmfinfo[NDMF]; 43 u_short dmfstd[] = { 0 }; 44 struct uba_driver dmfdriver = 45 { dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo }; 46 47 /* 48 * In this driver, "dmf" (unqualified) refers to the async portion 49 * of the dmf32, "dmfc" to the combo portion, "dmfs" to the sync 50 * portion, "dmfl" to the lp portion, and "dmfd" to the dr portion. 51 */ 52 struct dmfdevice 53 { 54 short dmfccsr0; /* combo csr 0 */ 55 short dmfccsr1; /* combo csr 1 */ 56 short dmfs[4]; 57 short dmfcsr; /* control-status register */ 58 short dmflpr; /* line parameter register */ 59 short dmfrbuf; /* receiver buffer (ro) */ 60 union { 61 u_short dmfirw; /* indirect register word */ 62 u_char dmfirc[2]; /* " " bytes */ 63 } dmfun; 64 short dmfl[2]; 65 short dmfd[4]; 66 }; 67 68 #define dmfrsp dmfrbuf /* receive silo parameter register (wo) */ 69 #define dmftbuf dmfun.dmfirc[0] /* transmit buffer */ 70 #define dmftsc dmfun.dmfirc[0] /* transmit silo count */ 71 #define dmfrms dmfun.dmfirc[1] /* receive modem status */ 72 #define dmflcr dmfun.dmfirc[0] /* line control register */ 73 #define dmftms dmfun.dmfirc[1] /* transmit modem status */ 74 #define dmftba dmfun.dmfirw /* transmit buffer address */ 75 #define dmftcc dmfun.dmfirw /* transmit character count */ 76 77 /* bits in dmfcsr */ 78 #define DMF_TI 0100000 /* transmit interrupt */ 79 #define DMF_TIE 0040000 /* transmit interrupt enable */ 80 #define DMF_NXM 0020000 /* non-existant memory */ 81 #define DMF_LIN 0003400 /* transmit line number */ 82 #define DMF_RI 0000200 /* receiver interrupt */ 83 #define DMF_RIE 0000100 /* receiver interrupt enable */ 84 #define DMF_CLR 0000040 /* master reset */ 85 #define DMF_IAD 0000037 /* indirect address register */ 86 87 #define DMFIR_TBUF 000 /* select tbuf indirect register */ 88 #define DMFIR_LCR 010 /* select lcr indirect register */ 89 #define DMFIR_TBA 020 /* select tba indirect register */ 90 #define DMFIR_TCC 030 /* select tcc indirect register */ 91 92 /* bits in dmflpr */ 93 #define BITS6 (01<<3) 94 #define BITS7 (02<<3) 95 #define BITS8 (03<<3) 96 #define TWOSB 0200 97 #define PENABLE 040 98 /* DEC manuals incorrectly say this bit causes generation of even parity. */ 99 #define OPAR 0100 100 101 #define DMF_IE (DMF_TIE|DMF_RIE) 102 103 #define DMF_SILOCNT 32 /* size of DMF output silo (per line) */ 104 105 /* bits in dmfrbuf */ 106 #define DMF_DSC 0004000 /* data set change */ 107 #define DMF_PE 0010000 /* parity error */ 108 #define DMF_FE 0020000 /* framing error */ 109 #define DMF_DO 0040000 /* data overrun */ 110 111 /* bits in dmfrms */ 112 #define DMF_USRR 0004 /* user modem signal (pin 25) */ 113 #define DMF_SR 0010 /* secondary receive */ 114 #define DMF_CTS 0020 /* clear to send */ 115 #define DMF_CAR 0040 /* carrier detect */ 116 #define DMF_RNG 0100 /* ring */ 117 #define DMF_DSR 0200 /* data set ready */ 118 119 /* bits in dmftms */ 120 #define DMF_USRW 0001 /* user modem signal (pin 18) */ 121 #define DMF_DTR 0002 /* data terminal ready */ 122 #define DMF_RATE 0004 /* data signal rate select */ 123 #define DMF_ST 0010 /* secondary transmit */ 124 #define DMF_RTS 0020 /* request to send */ 125 #define DMF_BRK 0040 /* pseudo break bit */ 126 #define DMF_PREEMPT 0200 /* preempt output */ 127 128 /* flags for modem control */ 129 #define DMF_ON (DMF_DTR|DMF_RTS) 130 #define DMF_OFF 0 131 132 /* bits in dmflcr */ 133 #define DMF_MIE 0040 /* modem interrupt enable */ 134 #define DMF_FLUSH 0020 /* flush transmit silo */ 135 #define DMF_RBRK 0010 /* real break bit */ 136 #define DMF_RE 0004 /* receive enable */ 137 #define DMF_AUTOX 0002 /* auto XON/XOFF */ 138 #define DMF_TE 0001 /* transmit enable */ 139 140 #define DMFLCR_ENA (DMF_MIE|DMF_RE|DMF_TE) 141 142 /* bits in dm lsr, copied from dh.c */ 143 #define DML_USR 0001000 /* usr modem sig, not a real DM bit */ 144 #define DML_DSR 0000400 /* data set ready, not a real DM bit */ 145 #define DML_RNG 0000200 /* ring */ 146 #define DML_CAR 0000100 /* carrier detect */ 147 #define DML_CTS 0000040 /* clear to send */ 148 #define DML_SR 0000020 /* secondary receive */ 149 #define DML_ST 0000010 /* secondary transmit */ 150 #define DML_RTS 0000004 /* request to send */ 151 #define DML_DTR 0000002 /* data terminal ready */ 152 #define DML_LE 0000001 /* line enable */ 153 154 /* 155 * Local variables for the driver 156 */ 157 char dmf_speeds[] = 158 { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 }; 159 160 struct tty dmf_tty[NDMF*8]; 161 char dmfsoftCAR[NDMF]; 162 #ifndef lint 163 int ndmf = NDMF*8; /* used by iostat */ 164 #endif 165 int dmfact; /* mask of active dmf's */ 166 int dmfstart(), ttrstrt(); 167 168 #ifdef DMFDMA 169 /* 170 * The clist space is mapped by the driver onto each UNIBUS. 171 * The UBACVT macro converts a clist space address for unibus uban 172 * into an i/o space address for the DMA routine. 173 */ 174 int dmf_ubinfo[MAXNUBA]; /* info about allocated unibus map */ 175 static int cbase[MAXNUBA]; /* base address in unibus map */ 176 #define UBACVT(x, uban) (cbase[uban] + ((x)-(char *)cfree)) 177 #endif 178 179 /* 180 * Routine for configuration to set dmf interrupt. 181 */ 182 /*ARGSUSED*/ 183 dmfprobe(reg, ctlr) 184 caddr_t reg; 185 int ctlr; 186 { 187 register int br, cvec; /* these are ``value-result'' */ 188 register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg; 189 190 #ifdef lint 191 br = 0; cvec = br; br = cvec; 192 dmfxint(0); dmfrint(0); 193 dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint(); 194 #endif 195 br = 0x15; 196 cvec = (uba_hd[numuba].uh_lastiv -= 4*8); 197 dmfaddr->dmfccsr0 = cvec >> 2; 198 /* NEED TO SAVE IT SOMEWHERE FOR OTHER DEVICES */ 199 return (sizeof (struct dmfdevice)); 200 } 201 202 /* 203 * Routine called to attach a dmf. 204 */ 205 dmfattach(ui) 206 struct uba_device *ui; 207 { 208 209 dmfsoftCAR[ui->ui_unit] = ui->ui_flags; 210 } 211 212 213 /* 214 * Open a DMF32 line, mapping the clist onto the uba if this 215 * is the first dmf on this uba. Turn on this dmf if this is 216 * the first use of it. 217 */ 218 /*ARGSUSED*/ 219 dmfopen(dev, flag) 220 dev_t dev; 221 { 222 register struct tty *tp; 223 register int unit, dmf; 224 register struct dmfdevice *addr; 225 register struct uba_device *ui; 226 int s; 227 228 unit = minor(dev); 229 dmf = unit >> 3; 230 if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0) 231 return (ENXIO); 232 tp = &dmf_tty[unit]; 233 if (tp->t_state&TS_XCLUDE && u.u_uid!=0) 234 return (EBUSY); 235 addr = (struct dmfdevice *)ui->ui_addr; 236 tp->t_addr = (caddr_t)addr; 237 tp->t_oproc = dmfstart; 238 tp->t_state |= TS_WOPEN; 239 /* 240 * While setting up state for this uba and this dmf, 241 * block uba resets which can clear the state. 242 */ 243 s = spl5(); 244 #ifdef DMFDMA 245 if (dmf_ubinfo[ui->ui_ubanum] == 0) { 246 dmf_ubinfo[ui->ui_ubanum] = 247 uballoc(ui->ui_ubanum, (caddr_t)cfree, 248 nclist*sizeof(struct cblock), 0); 249 cbase[ui->ui_ubanum] = dmf_ubinfo[ui->ui_ubanum]&0x3ffff; 250 } 251 #endif 252 if ((dmfact&(1<<dmf)) == 0) { 253 addr->dmfcsr |= DMF_IE; 254 dmfact |= (1<<dmf); 255 addr->dmfrsp = 1; /* DON'T KNOW WHAT TO SET IT TO YET */ 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 dmfparam(unit); 269 } 270 /* 271 * Wait for carrier, then process line discipline specific open. 272 */ 273 if ((dmfmctl(dev, DMF_ON, DMSET) & (DMF_CAR<<8)) || 274 (dmfsoftCAR[dmf] & (1<<(unit&07)))) 275 tp->t_state |= TS_CARR_ON; 276 s = spl5(); 277 while ((tp->t_state & TS_CARR_ON) == 0) { 278 tp->t_state |= TS_WOPEN; 279 sleep((caddr_t)&tp->t_rawq, TTIPRI); 280 } 281 splx(s); 282 return ((*linesw[tp->t_line].l_open)(dev, tp)); 283 } 284 285 /* 286 * Close a DMF32 line. 287 */ 288 /*ARGSUSED*/ 289 dmfclose(dev, flag) 290 dev_t dev; 291 int flag; 292 { 293 register struct tty *tp; 294 register unit; 295 296 unit = minor(dev); 297 tp = &dmf_tty[unit]; 298 (*linesw[tp->t_line].l_close)(tp); 299 (void) dmfmctl(unit, DMF_BRK, DMBIC); 300 if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0) 301 (void) dmfmctl(unit, DMF_OFF, DMSET); 302 ttyclose(tp); 303 } 304 305 dmfread(dev, uio) 306 dev_t dev; 307 struct uio *uio; 308 { 309 register struct tty *tp; 310 311 tp = &dmf_tty[minor(dev)]; 312 return ((*linesw[tp->t_line].l_read)(tp, uio)); 313 } 314 315 dmfwrite(dev, uio) 316 dev_t dev; 317 struct uio *uio; 318 { 319 register struct tty *tp; 320 321 tp = &dmf_tty[minor(dev)]; 322 return ((*linesw[tp->t_line].l_write)(tp, uio)); 323 } 324 325 /* 326 * DMF32 receiver interrupt. 327 */ 328 dmfrint(dmf) 329 int dmf; 330 { 331 register struct tty *tp; 332 register c; 333 register struct dmfdevice *addr; 334 register struct tty *tp0; 335 register struct uba_device *ui; 336 int overrun = 0; 337 338 ui = dmfinfo[dmf]; 339 if (ui == 0 || ui->ui_alive == 0) 340 return; 341 addr = (struct dmfdevice *)ui->ui_addr; 342 tp0 = &dmf_tty[dmf<<3]; 343 /* 344 * Loop fetching characters from the silo for this 345 * dmf until there are no more in the silo. 346 */ 347 while ((c = addr->dmfrbuf) < 0) { 348 tp = tp0 + ((c>>8)&07); 349 if (c & DMF_DSC) { 350 addr->dmfcsr = DMF_IE | DMFIR_TBUF | ((c>>8)&07); 351 if (addr->dmfrms & DMF_CAR) { 352 if ((tp->t_state & TS_CARR_ON) == 0) { 353 wakeup((caddr_t)&tp->t_rawq); 354 tp->t_state |= TS_CARR_ON; 355 } 356 } else { 357 if (tp->t_state & TS_CARR_ON) { 358 gsignal(tp->t_pgrp, SIGHUP); 359 gsignal(tp->t_pgrp, SIGCONT); 360 addr->dmfcsr = DMF_IE | DMFIR_LCR | 361 ((c>>8)&07); 362 addr->dmftms = 0; 363 flushtty(tp, FREAD|FWRITE); 364 } 365 tp->t_state &= ~TS_CARR_ON; 366 } 367 continue; 368 } 369 if ((tp->t_state&TS_ISOPEN)==0) { 370 wakeup((caddr_t)tp); 371 continue; 372 } 373 if (c & DMF_PE) 374 if ((tp->t_flags&(EVENP|ODDP))==EVENP 375 || (tp->t_flags&(EVENP|ODDP))==ODDP ) 376 continue; 377 if ((c & DMF_DO) && overrun == 0) { 378 printf("dmf%d: silo overflow\n", dmf); 379 overrun = 1; 380 } 381 if (c & DMF_FE) 382 /* 383 * At framing error (break) generate 384 * a null (in raw mode, for getty), or a 385 * interrupt (in cooked/cbreak mode). 386 */ 387 if (tp->t_flags&RAW) 388 c = 0; 389 else 390 c = tp->t_intrc; 391 #if NBK > 0 392 if (tp->t_line == NETLDISC) { 393 c &= 0177; 394 BKINPUT(c, tp); 395 } else 396 #endif 397 (*linesw[tp->t_line].l_rint)(c, tp); 398 } 399 } 400 401 /* 402 * Ioctl for DMF32. 403 */ 404 /*ARGSUSED*/ 405 dmfioctl(dev, cmd, data, flag) 406 dev_t dev; 407 caddr_t data; 408 { 409 register struct tty *tp; 410 register int unit = minor(dev); 411 int error; 412 413 tp = &dmf_tty[unit]; 414 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 415 if (error >= 0) 416 return (error); 417 error = ttioctl(tp, cmd, data, flag); 418 if (error >= 0) { 419 if (cmd == TIOCSETP || cmd == TIOCSETN) 420 dmfparam(unit); 421 return (error); 422 } 423 switch (cmd) { 424 425 case TIOCSBRK: 426 (void) dmfmctl(dev, DMF_BRK, DMBIS); 427 break; 428 429 case TIOCCBRK: 430 (void) dmfmctl(dev, DMF_BRK, DMBIC); 431 break; 432 433 case TIOCSDTR: 434 (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIS); 435 break; 436 437 case TIOCCDTR: 438 (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIC); 439 break; 440 441 case TIOCMSET: 442 (void) dmfmctl(dev, dmtodmf(*(int *)data), DMSET); 443 break; 444 445 case TIOCMBIS: 446 (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIS); 447 break; 448 449 case TIOCMBIC: 450 (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIC); 451 break; 452 453 case TIOCMGET: 454 *(int *)data = dmftodm(dmfmctl(dev, 0, DMGET)); 455 break; 456 457 default: 458 return (ENOTTY); 459 } 460 return (0); 461 } 462 463 dmtodmf(bits) 464 register int bits; 465 { 466 register int b; 467 468 b = bits & 012; 469 if (bits & DML_ST) b |= DMF_RATE; 470 if (bits & DML_RTS) b |= DMF_RTS; 471 if (bits & DML_USR) b |= DMF_USRW; 472 return(b); 473 } 474 475 dmftodm(bits) 476 register int bits; 477 { 478 register int b; 479 480 b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE; 481 if (bits & DMF_USRR) b |= DML_USR; 482 if (bits & DMF_RTS) b |= DML_RTS; 483 return(b); 484 } 485 486 487 /* 488 * Set parameters from open or stty into the DMF hardware 489 * registers. 490 */ 491 dmfparam(unit) 492 register int unit; 493 { 494 register struct tty *tp; 495 register struct dmfdevice *addr; 496 register int lpar, lcr; 497 int s; 498 499 tp = &dmf_tty[unit]; 500 addr = (struct dmfdevice *)tp->t_addr; 501 /* 502 * Block interrupts so parameters will be set 503 * before the line interrupts. 504 */ 505 s = spl5(); 506 addr->dmfcsr = (unit&07) | DMFIR_LCR | DMF_IE; 507 if ((tp->t_ispeed)==0) { 508 tp->t_state |= TS_HUPCLS; 509 (void) dmfmctl(unit, DMF_OFF, DMSET); 510 return; 511 } 512 lpar = (dmf_speeds[tp->t_ospeed]<<12) | (dmf_speeds[tp->t_ispeed]<<8); 513 lcr = DMFLCR_ENA; 514 if ((tp->t_ispeed) == B134) 515 lpar |= BITS6|PENABLE; 516 else if (tp->t_flags & (RAW|LITOUT)) 517 lpar |= BITS8; 518 else { 519 lpar |= BITS7|PENABLE; 520 /* CHECK FOR XON/XOFF AND SET lcr |= DMF_AUTOX; */ 521 } 522 if ((tp->t_flags&EVENP) == 0) 523 lpar |= OPAR; 524 if ((tp->t_ospeed) == B110) 525 lpar |= TWOSB; 526 lpar |= (unit&07); 527 addr->dmflpr = lpar; 528 addr->dmflcr = lcr; 529 splx(s); 530 } 531 532 /* 533 * DMF32 transmitter interrupt. 534 * Restart the idle line. 535 */ 536 dmfxint(dmf) 537 int dmf; 538 { 539 register struct tty *tp; 540 register struct dmfdevice *addr; 541 register struct uba_device *ui; 542 register int unit, t; 543 #ifdef DMFDMA 544 short cntr; 545 #endif 546 547 ui = dmfinfo[dmf]; 548 addr = (struct dmfdevice *)ui->ui_addr; 549 while ((t = addr->dmfcsr) & DMF_TI) { 550 unit = dmf*8 + ((t>>8)&07); 551 tp = &dmf_tty[unit]; 552 tp->t_state &= ~TS_BUSY; 553 if (t & DMF_NXM) { 554 printf("dmf%d: NXM line %d\n", dmf, unit&7); 555 /* SHOULD RESTART OR SOMETHING... */ 556 } 557 if (tp->t_state&TS_FLUSH) 558 tp->t_state &= ~TS_FLUSH; 559 #ifdef DMFDMA 560 else { 561 addr->dmfcsr = DMFIR_TBUF | DMF_IE | (unit&07); 562 if (addr->dmftsc == 0) { 563 /* 564 * Do arithmetic in a short to make up 565 * for lost 16&17 bits. 566 */ 567 addr->dmfcsr = DMFIR_TBA | DMF_IE | (unit&07); 568 cntr = addr->dmftba - 569 UBACVT(tp->t_outq.c_cf, ui->ui_ubanum); 570 ndflush(&tp->t_outq, (int)cntr); 571 } 572 } 573 #endif 574 if (tp->t_line) 575 (*linesw[tp->t_line].l_start)(tp); 576 else 577 dmfstart(tp); 578 } 579 } 580 581 /* 582 * Start (restart) transmission on the given DMF32 line. 583 */ 584 dmfstart(tp) 585 register struct tty *tp; 586 { 587 register struct dmfdevice *addr; 588 register int unit, nch; 589 int s; 590 591 unit = minor(tp->t_dev); 592 unit &= 07; 593 addr = (struct dmfdevice *)tp->t_addr; 594 595 /* 596 * Must hold interrupts in following code to prevent 597 * state of the tp from changing. 598 */ 599 s = spl5(); 600 /* 601 * If it's currently active, or delaying, no need to do anything. 602 */ 603 if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 604 goto out; 605 /* 606 * If there are still characters in the silo, 607 * just reenable the transmitter. 608 */ 609 addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 610 if (addr->dmftsc) { 611 addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 612 addr->dmflcr |= DMF_TE; 613 tp->t_state |= TS_BUSY; 614 goto out; 615 } 616 /* 617 * If there are sleepers, and output has drained below low 618 * water mark, wake up the sleepers. 619 */ 620 if ((tp->t_state&TS_ASLEEP) && tp->t_outq.c_cc<=TTLOWAT(tp)) { 621 tp->t_state &= ~TS_ASLEEP; 622 wakeup((caddr_t)&tp->t_outq); 623 } 624 /* 625 * Now restart transmission unless the output queue is 626 * empty. 627 */ 628 if (tp->t_outq.c_cc == 0) 629 goto out; 630 if (tp->t_flags & (RAW|LITOUT)) 631 nch = ndqb(&tp->t_outq, 0); 632 else { 633 nch = ndqb(&tp->t_outq, 0200); 634 /* 635 * If first thing on queue is a delay process it. 636 */ 637 if (nch == 0) { 638 nch = getc(&tp->t_outq); 639 timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6); 640 tp->t_state |= TS_TIMEOUT; 641 goto out; 642 } 643 } 644 /* 645 * If characters to transmit, restart transmission. 646 */ 647 if (nch) { 648 #ifdef DMFDMA 649 addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 650 addr->dmflcr |= DMF_TE; 651 car = UBACVT(tp->t_outq.c_cf, dmfinfo[dmf]->ui_ubanum); 652 addr->dmfcsr = DMF_IE | DMFIR_TBA | unit; 653 addr->dmftba = car; 654 addr->dmftcc = ((car>>2)&0xc000) | nch; 655 #else 656 register char *cp = tp->t_outq.c_cf; 657 register int i; 658 659 nch = MIN(nch, DMF_SILOCNT); 660 addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 661 addr->dmflcr |= DMF_TE; 662 addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 663 for (i = 0; i < nch; i++) 664 addr->dmftbuf = *cp++; 665 ndflush(&tp->t_outq, nch); 666 #endif 667 tp->t_state |= TS_BUSY; 668 } 669 out: 670 splx(s); 671 } 672 673 /* 674 * Stop output on a line, e.g. for ^S/^Q or output flush. 675 */ 676 /*ARGSUSED*/ 677 dmfstop(tp, flag) 678 register struct tty *tp; 679 { 680 register struct dmfdevice *addr; 681 register int unit, s; 682 683 addr = (struct dmfdevice *)tp->t_addr; 684 /* 685 * Block input/output interrupts while messing with state. 686 */ 687 s = spl5(); 688 if (tp->t_state & TS_BUSY) { 689 /* 690 * Device is transmitting; stop output 691 * by selecting the line and disabling 692 * the transmitter. If this is a flush 693 * request then flush the output silo, 694 * otherwise we will pick up where we 695 * left off by enabling the transmitter. 696 */ 697 unit = minor(tp->t_dev); 698 addr->dmfcsr = DMFIR_LCR | (unit&07) | DMF_IE; 699 addr->dmflcr &= ~DMF_TE; 700 if ((tp->t_state&TS_TTSTOP)==0) { 701 tp->t_state |= TS_FLUSH; 702 addr->dmflcr |= DMF_FLUSH; 703 } else 704 tp->t_state &= ~TS_BUSY; 705 } 706 splx(s); 707 } 708 709 /* 710 * DMF32 modem control 711 */ 712 dmfmctl(dev, bits, how) 713 dev_t dev; 714 int bits, how; 715 { 716 register struct dmfdevice *dmfaddr; 717 register int unit, mbits, lcr; 718 int s; 719 720 unit = minor(dev); 721 dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr); 722 unit &= 07; 723 s = spl5(); 724 dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 725 mbits = dmfaddr->dmfrms << 8; 726 dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 727 mbits |= dmfaddr->dmftms; 728 lcr = dmfaddr->dmflcr; 729 switch (how) { 730 case DMSET: 731 mbits = bits; 732 break; 733 734 case DMBIS: 735 mbits |= bits; 736 break; 737 738 case DMBIC: 739 mbits &= ~bits; 740 break; 741 742 case DMGET: 743 (void) splx(s); 744 return(mbits); 745 } 746 dmfaddr->dmftms = mbits&037; 747 if (mbits & DMF_BRK) 748 lcr |= DMF_RBRK; 749 else 750 lcr &= ~DMF_RBRK; 751 dmfaddr->dmflcr = lcr; 752 (void) splx(s); 753 return(mbits); 754 } 755 756 /* 757 * Reset state of driver if UBA reset was necessary. 758 * Reset the csr, lpr, and lcr registers on open lines, and 759 * restart transmitters. 760 */ 761 dmfreset(uban) 762 int uban; 763 { 764 register int dmf, unit; 765 register struct tty *tp; 766 register struct uba_device *ui; 767 register struct dmfdevice *addr; 768 int i; 769 770 #ifdef DMFDMA 771 if (dmf_ubinfo[uban] == 0) 772 return; 773 dmf_ubinfo[uban] = uballoc(uban, (caddr_t)cfree, 774 nclist*sizeof (struct cblock), 0); 775 cbase[uban] = dmf_ubinfo[uban]&0x3ffff; 776 #endif 777 for (dmf = 0; dmf < NDMF; dmf++) { 778 ui = dmfinfo[dmf]; 779 if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 780 continue; 781 printf(" dmf%d", dmf); 782 addr = (struct dmfdevice *)ui->ui_addr; 783 addr->dmfcsr = DMF_IE; 784 addr->dmfrsp = 1; 785 unit = dmf * 8; 786 for (i = 0; i < 8; i++) { 787 tp = &dmf_tty[unit]; 788 if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 789 dmfparam(unit); 790 (void) dmfmctl(unit, DMF_ON, DMSET); 791 tp->t_state &= ~TS_BUSY; 792 dmfstart(tp); 793 } 794 unit++; 795 } 796 } 797 } 798 799 /* stubs for interrupt routines for devices not yet supported */ 800 801 dmfsrint() { printf("dmfsrint\n"); } 802 803 dmfsxint() { printf("dmfsxint\n"); } 804 805 dmfdaint() { printf("dmfdaint\n"); } 806 807 dmfdbint() { printf("dmfdbint\n"); } 808 809 dmflint() { printf("dmflint\n"); } 810 #endif 811