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