1 /* 2 * Copyright (c) 1982 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)dmf.c 6.19 (Berkeley) 04/12/86 7 */ 8 9 #include "dmf.h" 10 #if NDMF > 0 11 /* 12 * DMF32 driver 13 * 14 * 15 * TODO: 16 * test with modem 17 * load as much as possible into silo 18 * use auto XON/XOFF 19 * test reset code 20 **************************** 21 * DMF32 line printer driver 22 * 23 * the line printer on dmfx is indicated by a minor device code of 128+x 24 * 25 * the flags field of the config file is interpreted like so: 26 * bits meaning 27 * ---- ------- 28 * 0-7 soft carrier bits for ttys part of dmf32 29 * 8-15 number of cols/line on the line printer 30 * if 0, 132 will be used. 31 * 16-23 number of lines/page on the line printer 32 * if 0, 66 will be used. 33 * 24 if 1 DO NOT use the auto format mode of the 34 * line printer parallel port 35 */ 36 #include "../machine/pte.h" 37 38 #include "bk.h" 39 #include "uba.h" 40 #include "param.h" 41 #include "conf.h" 42 #include "dir.h" 43 #include "user.h" 44 #include "proc.h" 45 #include "ioctl.h" 46 #include "tty.h" 47 #include "map.h" 48 #include "buf.h" 49 #include "vm.h" 50 #include "bkmac.h" 51 #include "clist.h" 52 #include "file.h" 53 #include "uio.h" 54 #include "kernel.h" 55 #include "syslog.h" 56 57 #include "ubareg.h" 58 #include "ubavar.h" 59 #include "dmfreg.h" 60 61 /* 62 * Definition of the driver for the auto-configuration program. 63 */ 64 int dmfprobe(), dmfattach(), dmfrint(), dmfxint(); 65 int dmflint(); 66 struct uba_device *dmfinfo[NDMF]; 67 u_short dmfstd[] = { 0 }; 68 struct uba_driver dmfdriver = 69 { dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo }; 70 71 int dmf_timeout = 10; /* silo timeout, in ms */ 72 int dmf_mindma = 4; /* don't dma below this point */ 73 74 /* 75 * Local variables for the driver 76 */ 77 char dmf_speeds[] = 78 { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 }; 79 80 #ifndef PORTSELECTOR 81 #define ISPEED B9600 82 #define IFLAGS (EVENP|ODDP|ECHO) 83 #else 84 #define ISPEED B4800 85 #define IFLAGS (EVENP|ODDP) 86 #endif 87 88 struct tty dmf_tty[NDMF*8]; 89 char dmfsoftCAR[NDMF]; 90 91 struct dmfl_softc { 92 u_int dmfl_state; /* soft state bits */ 93 int dmfl_info; /* uba info */ 94 u_short dmfl_lines; /* lines per page (66 def.) */ 95 u_short dmfl_cols; /* cols per line (132 def.) */ 96 u_short dmfl_format; /* fflag for auto form feed */ 97 char dmfl_buf[DMFL_BUFSIZ]; 98 } dmfl_softc[NDMF]; 99 100 /* 101 * convert device number into DMF line printer unit number 102 */ 103 #define DMFL_UNIT(d) (minor(d)&0xF) /* up to 16 DMFs */ 104 105 #define ASLP 1 /* waiting for interrupt from dmf */ 106 #define OPEN 2 /* line printer is open */ 107 #define ERROR 4 /* error while printing, driver 108 refuses to do anything till closed */ 109 #define MOREIO 8 /* more data for printer */ 110 111 #ifndef lint 112 int ndmf = NDMF*8; /* used by iostat */ 113 #endif 114 int dmfact; /* mask of active dmf's */ 115 int dmfstart(), ttrstrt(); 116 117 /* 118 * The clist space is mapped by the driver onto each UNIBUS. 119 * The UBACVT macro converts a clist space address for unibus uban 120 * into an i/o space address for the DMA routine. 121 */ 122 int dmf_ubinfo[NUBA]; /* info about allocated unibus map */ 123 int cbase[NUBA]; /* base address in unibus map */ 124 #define UBACVT(x, uban) (cbase[uban] + ((x)-(char *)cfree)) 125 char dmf_dma[NDMF*8]; 126 127 /* 128 * Routine for configuration to set dmf interrupt. 129 */ 130 /*ARGSUSED*/ 131 dmfprobe(reg, ctlr) 132 caddr_t reg; 133 struct uba_device *ctlr; 134 { 135 register int br, cvec; /* these are ``value-result'' */ 136 register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg; 137 register int i; 138 register unsigned int a; 139 static char *dmfdevs[]= 140 {"parallel","printer","synch","asynch"}; 141 unsigned int dmfoptions; 142 static int (*intrv[3])() = { (int (*)())0, (int (*)())0, (int (*)())0 }; 143 144 #ifdef lint 145 br = 0; cvec = br; br = cvec; 146 dmfxint(0); dmfrint(0); 147 dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint(0); 148 #endif 149 /* 150 * Pick the usual size DMF vector here (don't decrement it here). 151 * grab configuration; note that the DMF32 152 * doesn't seem to put the right bits in this 153 * register until AFTER the interrupt vector is set. 154 */ 155 br = 0x15; 156 cvec = (uba_hd[numuba].uh_lastiv - 4*8); 157 dmfaddr->dmfccsr0 = (cvec >> 2); 158 dmfoptions = dmfaddr->dmfccsr0 & DMFC_CONFMASK; 159 160 /* catch a couple of special cases: Able vmz/32n and vmz/lp */ 161 if (dmfoptions == DMFC_ASYNC) { 162 /* Async portion only */ 163 164 cvec = (uba_hd[numuba].uh_lastiv -= 8); 165 dmfaddr->dmfccsr0 = (cvec - 2*8) >> 2; 166 intrv[0] = ctlr->ui_intr[4]; 167 intrv[1] = ctlr->ui_intr[5]; 168 ctlr->ui_intr = intrv; 169 } else if (dmfoptions == DMFC_LP) { 170 /* LP portion only */ 171 172 cvec = (uba_hd[numuba].uh_lastiv -= 8); 173 ctlr->ui_intr = &ctlr->ui_intr[6]; 174 } else if (dmfoptions == (DMFC_LP|DMFC_ASYNC)) { 175 /* LP ans Async portions only */ 176 177 cvec = (uba_hd[numuba].uh_lastiv -= 2*8); 178 ctlr->ui_intr = &ctlr->ui_intr[4]; 179 } else { 180 /* All other configurations get everything */ 181 182 cvec = (uba_hd[numuba].uh_lastiv -= 4*8); 183 } 184 a = (dmfoptions >> 12) & 0xf; 185 printf("dmf%d:", ctlr->ui_unit); 186 for (i = 0; a != 0; ++i, a >>= 1) { 187 if (a & 1) 188 printf(" %s",dmfdevs[i]); 189 } 190 printf(".\n"); 191 192 if (dmfoptions & DMFC_LP) 193 dmfaddr->dmfl_ctrl = DMFL_RESET; 194 return (sizeof (struct dmfdevice)); 195 } 196 197 /* 198 * Routine called to attach a dmf. 199 */ 200 dmfattach(ui) 201 struct uba_device *ui; 202 { 203 register int cols = (ui->ui_flags>>8) & 0xff; 204 register int lines = (ui->ui_flags>>16) & 0xff; 205 206 dmfsoftCAR[ui->ui_unit] = ui->ui_flags & 0xff; 207 dmfl_softc[ui->ui_unit].dmfl_cols = cols == 0 ? DMFL_DEFCOLS : cols; 208 dmfl_softc[ui->ui_unit].dmfl_lines = lines == 0 ? DMFL_DEFLINES : lines; 209 if ((ui->ui_flags >> 24) & 0x1) 210 dmfl_softc[ui->ui_unit].dmfl_format = (2 << 8); 211 else 212 dmfl_softc[ui->ui_unit].dmfl_format = (2 << 8) | DMFL_FORMAT; 213 cbase[ui->ui_ubanum] = -1; 214 } 215 216 217 /* 218 * Open a DMF32 line, mapping the clist onto the uba if this 219 * is the first dmf on this uba. Turn on this dmf if this is 220 * the first use of it. 221 */ 222 /*ARGSUSED*/ 223 dmfopen(dev, flag) 224 dev_t dev; 225 { 226 register struct tty *tp; 227 register int unit, dmf; 228 register struct dmfdevice *addr; 229 register struct uba_device *ui; 230 int s; 231 232 unit = minor(dev); 233 if (unit & 0200) 234 return (dmflopen(dev,flag)); 235 dmf = unit >> 3; 236 if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0) 237 return (ENXIO); 238 tp = &dmf_tty[unit]; 239 if (tp->t_state&TS_XCLUDE && u.u_uid!=0) 240 return (EBUSY); 241 addr = (struct dmfdevice *)ui->ui_addr; 242 tp->t_addr = (caddr_t)addr; 243 tp->t_oproc = dmfstart; 244 tp->t_state |= TS_WOPEN; 245 /* 246 * While setting up state for this uba and this dmf, 247 * block uba resets which can clear the state. 248 */ 249 s = spltty(); 250 if (cbase[ui->ui_ubanum] == -1) { 251 dmf_ubinfo[ui->ui_ubanum] = 252 uballoc(ui->ui_ubanum, (caddr_t)cfree, 253 nclist*sizeof(struct cblock), 0); 254 cbase[ui->ui_ubanum] = UBAI_ADDR(dmf_ubinfo[ui->ui_ubanum]); 255 } 256 if ((dmfact&(1<<dmf)) == 0) { 257 addr->dmfcsr |= DMF_IE; 258 dmfact |= (1<<dmf); 259 addr->dmfrsp = dmf_timeout; 260 } 261 splx(s); 262 /* 263 * If this is first open, initialize tty state to default. 264 */ 265 if ((tp->t_state&TS_ISOPEN) == 0) { 266 ttychars(tp); 267 #ifndef PORTSELECTOR 268 if (tp->t_ispeed == 0) { 269 #else 270 tp->t_state |= TS_HUPCLS; 271 #endif PORTSELECTOR 272 tp->t_ispeed = ISPEED; 273 tp->t_ospeed = ISPEED; 274 tp->t_flags = IFLAGS; 275 #ifndef PORTSELECTOR 276 } 277 #endif PORTSELECTOR 278 dmfparam(unit); 279 } 280 /* 281 * Wait for carrier, then process line discipline specific open. 282 */ 283 s = spltty(); 284 for (;;) { 285 if ((dmfmctl(dev, DMF_ON, DMSET) & (DMF_CAR<<8)) || 286 (dmfsoftCAR[dmf] & (1<<(unit&07)))) 287 tp->t_state |= TS_CARR_ON; 288 if (tp->t_state & TS_CARR_ON) 289 break; 290 tp->t_state |= TS_WOPEN; 291 sleep((caddr_t)&tp->t_rawq, TTIPRI); 292 } 293 splx(s); 294 return ((*linesw[tp->t_line].l_open)(dev, tp)); 295 } 296 297 /* 298 * Close a DMF32 line. 299 */ 300 /*ARGSUSED*/ 301 dmfclose(dev, flag) 302 dev_t dev; 303 int flag; 304 { 305 register struct tty *tp; 306 register unit; 307 308 unit = minor(dev); 309 if (unit & 0200) { 310 dmflclose(dev,flag); 311 return; 312 } 313 314 tp = &dmf_tty[unit]; 315 (*linesw[tp->t_line].l_close)(tp); 316 (void) dmfmctl(unit, DMF_BRK, DMBIC); 317 if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0) 318 (void) dmfmctl(unit, DMF_OFF, DMSET); 319 ttyclose(tp); 320 } 321 322 dmfread(dev, uio) 323 dev_t dev; 324 struct uio *uio; 325 { 326 register struct tty *tp; 327 328 if (minor(dev) & 0200) 329 return(ENXIO); 330 tp = &dmf_tty[minor(dev)]; 331 return ((*linesw[tp->t_line].l_read)(tp, uio)); 332 } 333 334 dmfwrite(dev, uio) 335 dev_t dev; 336 struct uio *uio; 337 { 338 register struct tty *tp; 339 340 if (minor(dev) & 0200) 341 return (dmflwrite(dev,uio)); 342 tp = &dmf_tty[minor(dev)]; 343 return ((*linesw[tp->t_line].l_write)(tp, uio)); 344 } 345 346 /* 347 * DMF32 receiver interrupt. 348 */ 349 dmfrint(dmf) 350 int dmf; 351 { 352 register c; 353 register struct tty *tp; 354 register struct dmfdevice *addr; 355 register struct tty *tp0; 356 int unit; 357 int overrun = 0; 358 register struct uba_device *ui; 359 360 ui = dmfinfo[dmf]; 361 if (ui == 0 || ui->ui_alive == 0) 362 return; 363 addr = (struct dmfdevice *)ui->ui_addr; 364 tp0 = &dmf_tty[dmf * 8]; 365 /* 366 * Loop fetching characters from the silo for this 367 * dmf until there are no more in the silo. 368 */ 369 while ((c = addr->dmfrbuf) < 0) { 370 371 unit = (c >> 8) & 07; 372 tp = tp0 + unit; 373 if (c & DMF_DSC) { 374 addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 375 if (addr->dmfrms & DMF_CAR) 376 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 377 else if ((dmfsoftCAR[dmf] & (1 << unit)) == 0 && 378 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) { 379 addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 380 addr->dmflctms = DMFLCR_ENA; 381 } 382 continue; 383 } 384 if ((tp->t_state&TS_ISOPEN) == 0) { 385 wakeup((caddr_t)&tp->t_rawq); 386 #ifdef PORTSELECTOR 387 if ((tp->t_state & TS_WOPEN) == 0) 388 #endif 389 continue; 390 } 391 if (c & (DMF_PE|DMF_DO|DMF_FE)) { 392 if (c & DMF_PE) 393 if ((tp->t_flags & (EVENP|ODDP)) == EVENP 394 || (tp->t_flags & (EVENP|ODDP)) == ODDP) 395 continue; 396 if ((c & DMF_DO) && overrun == 0) { 397 log(LOG_WARNING, "dmf%d: silo overflow\n", dmf); 398 overrun = 1; 399 } 400 if (c & DMF_FE) 401 /* 402 * At framing error (break) generate 403 * a null (in raw mode, for getty), or a 404 * interrupt (in cooked/cbreak mode). 405 */ 406 if (tp->t_flags & RAW) 407 c = 0; 408 else 409 c = tp->t_intrc; 410 } 411 #if NBK > 0 412 if (tp->t_line == NETLDISC) { 413 c &= 0177; 414 BKINPUT(c, tp); 415 } else 416 #endif 417 (*linesw[tp->t_line].l_rint)(c, tp); 418 } 419 } 420 421 /* 422 * Ioctl for DMF32. 423 */ 424 /*ARGSUSED*/ 425 dmfioctl(dev, cmd, data, flag) 426 dev_t dev; 427 caddr_t data; 428 { 429 register struct tty *tp; 430 register int unit = minor(dev); 431 int error; 432 433 if (unit & 0200) 434 return (ENOTTY); 435 tp = &dmf_tty[unit]; 436 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 437 if (error >= 0) 438 return (error); 439 error = ttioctl(tp, cmd, data, flag); 440 if (error >= 0) { 441 if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS || 442 cmd == TIOCLBIC || cmd == TIOCLSET) 443 dmfparam(unit); 444 return (error); 445 } 446 switch (cmd) { 447 448 case TIOCSBRK: 449 (void) dmfmctl(dev, DMF_BRK, DMBIS); 450 break; 451 452 case TIOCCBRK: 453 (void) dmfmctl(dev, DMF_BRK, DMBIC); 454 break; 455 456 case TIOCSDTR: 457 (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIS); 458 break; 459 460 case TIOCCDTR: 461 (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIC); 462 break; 463 464 case TIOCMSET: 465 (void) dmfmctl(dev, dmtodmf(*(int *)data), DMSET); 466 break; 467 468 case TIOCMBIS: 469 (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIS); 470 break; 471 472 case TIOCMBIC: 473 (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIC); 474 break; 475 476 case TIOCMGET: 477 *(int *)data = dmftodm(dmfmctl(dev, 0, DMGET)); 478 break; 479 480 default: 481 return (ENOTTY); 482 } 483 return (0); 484 } 485 486 dmtodmf(bits) 487 register int bits; 488 { 489 register int b; 490 491 b = bits & 012; 492 if (bits & DML_ST) b |= DMF_RATE; 493 if (bits & DML_RTS) b |= DMF_RTS; 494 if (bits & DML_USR) b |= DMF_USRW; 495 return(b); 496 } 497 498 dmftodm(bits) 499 register int bits; 500 { 501 register int b; 502 503 b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE; 504 if (bits & DMF_USRR) b |= DML_USR; 505 if (bits & DMF_RTS) b |= DML_RTS; 506 return(b); 507 } 508 509 510 /* 511 * Set parameters from open or stty into the DMF hardware 512 * registers. 513 */ 514 dmfparam(unit) 515 register int unit; 516 { 517 register struct tty *tp; 518 register struct dmfdevice *addr; 519 register int lpar, lcr; 520 int s; 521 522 tp = &dmf_tty[unit]; 523 addr = (struct dmfdevice *)tp->t_addr; 524 /* 525 * Block interrupts so parameters will be set 526 * before the line interrupts. 527 */ 528 s = spltty(); 529 addr->dmfcsr = (unit&07) | DMFIR_LCR | DMF_IE; 530 if ((tp->t_ispeed)==0) { 531 tp->t_state |= TS_HUPCLS; 532 (void) dmfmctl(unit, DMF_OFF, DMSET); 533 splx(s); 534 return; 535 } 536 lpar = (dmf_speeds[tp->t_ospeed]<<12) | (dmf_speeds[tp->t_ispeed]<<8); 537 lcr = DMFLCR_ENA; 538 if ((tp->t_ispeed) == B134) 539 lpar |= BITS6|PENABLE; 540 else if (tp->t_flags & (RAW|LITOUT|PASS8)) 541 lpar |= BITS8; 542 else { 543 lpar |= BITS7|PENABLE; 544 /* CHECK FOR XON/XOFF AND SET lcr |= DMF_AUTOX; */ 545 } 546 if (tp->t_flags&EVENP) 547 lpar |= EPAR; 548 if ((tp->t_ospeed) == B110) 549 lpar |= TWOSB; 550 lpar |= (unit&07); 551 addr->dmflpr = lpar; 552 addr->dmflctms = (addr->dmflctms &~ 0xff) | lcr; 553 splx(s); 554 } 555 556 /* 557 * DMF32 transmitter interrupt. 558 * Restart the idle line. 559 */ 560 dmfxint(dmf) 561 int dmf; 562 { 563 int unit0 = dmf * 8; 564 struct tty *tp0 = &dmf_tty[unit0]; 565 register struct tty *tp; 566 register struct dmfdevice *addr; 567 register struct uba_device *ui; 568 register int t; 569 short cntr; 570 571 ui = dmfinfo[dmf]; 572 addr = (struct dmfdevice *)ui->ui_addr; 573 while ((t = addr->dmfcsr) & DMF_TI) { 574 if (t & DMF_NXM) 575 /* SHOULD RESTART OR SOMETHING... */ 576 printf("dmf%d: NXM line %d\n", dmf, t >> 8 & 7); 577 t = t >> 8 & 7; 578 tp = tp0 + t; 579 tp->t_state &= ~TS_BUSY; 580 if (tp->t_state&TS_FLUSH) 581 tp->t_state &= ~TS_FLUSH; 582 else if (dmf_dma[unit0 + t]) { 583 /* 584 * Do arithmetic in a short to make up 585 * for lost 16&17 bits. 586 */ 587 addr->dmfcsr = DMFIR_TBA | DMF_IE | t; 588 cntr = addr->dmftba - 589 UBACVT(tp->t_outq.c_cf, ui->ui_ubanum); 590 ndflush(&tp->t_outq, (int)cntr); 591 } 592 if (tp->t_line) 593 (*linesw[tp->t_line].l_start)(tp); 594 else 595 dmfstart(tp); 596 } 597 } 598 599 /* 600 * Start (restart) transmission on the given DMF32 line. 601 */ 602 dmfstart(tp) 603 register struct tty *tp; 604 { 605 register struct dmfdevice *addr; 606 register int unit, nch; 607 int s; 608 register int dmf; 609 610 unit = minor(tp->t_dev); 611 dmf = unit >> 3; 612 unit &= 07; 613 addr = (struct dmfdevice *)tp->t_addr; 614 615 /* 616 * Must hold interrupts in following code to prevent 617 * state of the tp from changing. 618 */ 619 s = spltty(); 620 /* 621 * If it's currently active, or delaying, no need to do anything. 622 */ 623 if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 624 goto out; 625 /* 626 * If there are still characters in the silo, 627 * just reenable the transmitter. 628 */ 629 addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 630 if (addr->dmftsc) { 631 addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 632 addr->dmflctms = addr->dmflctms | DMF_TE; 633 tp->t_state |= TS_BUSY; 634 goto out; 635 } 636 /* 637 * If there are sleepers, and output has drained below low 638 * water mark, wake up the sleepers. 639 */ 640 if (tp->t_outq.c_cc<=TTLOWAT(tp)) { 641 if (tp->t_state&TS_ASLEEP) { 642 tp->t_state &= ~TS_ASLEEP; 643 wakeup((caddr_t)&tp->t_outq); 644 } 645 if (tp->t_wsel) { 646 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 647 tp->t_wsel = 0; 648 tp->t_state &= ~TS_WCOLL; 649 } 650 } 651 /* 652 * Now restart transmission unless the output queue is 653 * empty. 654 */ 655 if (tp->t_outq.c_cc == 0) 656 goto out; 657 if (tp->t_flags & (RAW|LITOUT)) 658 nch = ndqb(&tp->t_outq, 0); 659 else { 660 if ((nch = ndqb(&tp->t_outq, 0200)) == 0) { 661 /* 662 * If first thing on queue is a delay process it. 663 */ 664 nch = getc(&tp->t_outq); 665 timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6); 666 tp->t_state |= TS_TIMEOUT; 667 goto out; 668 } 669 } 670 /* 671 * If characters to transmit, restart transmission. 672 */ 673 if (nch >= dmf_mindma) { 674 register car; 675 676 dmf_dma[minor(tp->t_dev)] = 1; 677 addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 678 addr->dmflctms = addr->dmflctms | DMF_TE; 679 car = UBACVT(tp->t_outq.c_cf, dmfinfo[dmf]->ui_ubanum); 680 addr->dmfcsr = DMF_IE | DMFIR_TBA | unit; 681 addr->dmftba = car; 682 addr->dmftcc = ((car >> 2) & 0xc000) | nch; 683 tp->t_state |= TS_BUSY; 684 } else if (nch) { 685 register char *cp = tp->t_outq.c_cf; 686 register int i; 687 688 dmf_dma[minor(tp->t_dev)] = 0; 689 nch = MIN(nch, DMF_SILOCNT); 690 addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 691 addr->dmflctms = addr->dmflctms | DMF_TE; 692 addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 693 for (i = 0; i < nch; i++) 694 addr->dmftbuf = *cp++; 695 ndflush(&tp->t_outq, nch); 696 tp->t_state |= TS_BUSY; 697 } 698 out: 699 splx(s); 700 } 701 702 /* 703 * Stop output on a line, e.g. for ^S/^Q or output flush. 704 */ 705 /*ARGSUSED*/ 706 dmfstop(tp, flag) 707 register struct tty *tp; 708 { 709 register struct dmfdevice *addr; 710 register unit = minor(tp->t_dev) & 7; 711 int s; 712 713 addr = (struct dmfdevice *)tp->t_addr; 714 /* 715 * Block input/output interrupts while messing with state. 716 */ 717 s = spltty(); 718 if (flag) { 719 addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 720 if (addr->dmftsc) { 721 /* 722 * Flush regardless of whether we're transmitting 723 * (TS_BUSY), if the silo contains untransmitted 724 * characters. 725 */ 726 addr->dmfcsr = DMFIR_LCR | unit | DMF_IE; 727 addr->dmflctms = addr->dmflctms | DMF_TE | DMF_FLUSH; 728 /* this will interrupt so let dmfxint handle the rest */ 729 tp->t_state |= TS_FLUSH|TS_BUSY; 730 } 731 } else { 732 if (tp->t_state & TS_BUSY) { 733 /* 734 * Stop transmission by disabling 735 * the transmitter. We'll pick up where we 736 * left off by reenabling in dmfstart. 737 */ 738 addr->dmfcsr = DMFIR_LCR | unit | DMF_IE; 739 addr->dmflctms = addr->dmflctms &~ DMF_TE; 740 /* no interrupt here */ 741 tp->t_state &= ~TS_BUSY; 742 } 743 } 744 splx(s); 745 } 746 747 /* 748 * DMF32 modem control 749 */ 750 dmfmctl(dev, bits, how) 751 dev_t dev; 752 int bits, how; 753 { 754 register struct dmfdevice *dmfaddr; 755 register int unit, mbits, lcr; 756 int s; 757 758 unit = minor(dev); 759 dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr); 760 unit &= 07; 761 s = spltty(); 762 dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 763 mbits = dmfaddr->dmfrms << 8; 764 dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 765 lcr = dmfaddr->dmflctms; 766 mbits |= (lcr & 0xff00) >> 8; 767 switch (how) { 768 case DMSET: 769 mbits = (mbits &0xff00) | bits; 770 break; 771 772 case DMBIS: 773 mbits |= bits; 774 break; 775 776 case DMBIC: 777 mbits &= ~bits; 778 break; 779 780 case DMGET: 781 (void) splx(s); 782 return(mbits); 783 } 784 if (mbits & DMF_BRK) 785 lcr |= DMF_RBRK; 786 else 787 lcr &= ~DMF_RBRK; 788 dmfaddr->dmflctms = ((mbits & 037) << 8) | (lcr & 0xff); 789 (void) splx(s); 790 return(mbits); 791 } 792 793 /* 794 * Reset state of driver if UBA reset was necessary. 795 * Reset the csr, lpr, and lcr registers on open lines, and 796 * restart transmitters. 797 */ 798 dmfreset(uban) 799 int uban; 800 { 801 register int dmf, unit; 802 register struct tty *tp; 803 register struct uba_device *ui; 804 register struct dmfdevice *addr; 805 int i; 806 807 for (dmf = 0; dmf < NDMF; dmf++) { 808 ui = dmfinfo[dmf]; 809 if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 810 continue; 811 printf(" dmf%d", dmf); 812 if (dmf_ubinfo[uban]) { 813 dmf_ubinfo[uban] = uballoc(uban, (caddr_t)cfree, 814 nclist*sizeof (struct cblock), 0); 815 cbase[uban] = UBAI_ADDR(dmf_ubinfo[uban]); 816 } 817 addr = (struct dmfdevice *)ui->ui_addr; 818 addr->dmfcsr = DMF_IE; 819 addr->dmfrsp = dmf_timeout; 820 unit = dmf * 8; 821 for (i = 0; i < 8; i++) { 822 tp = &dmf_tty[unit]; 823 if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 824 dmfparam(unit); 825 (void) dmfmctl(unit, DMF_ON, DMSET); 826 tp->t_state &= ~TS_BUSY; 827 dmfstart(tp); 828 } 829 unit++; 830 } 831 } 832 } 833 834 /* 835 * dmflopen -- open the line printer port on a dmf32 836 */ 837 /* ARGSUSED */ 838 dmflopen(dev, flag) 839 dev_t dev; 840 int flag; 841 { 842 register int dmf; 843 register struct dmfl_softc *sc; 844 register struct uba_device *ui; 845 register struct dmfdevice *addr; 846 847 dmf = DMFL_UNIT(dev); 848 if (dmf >= NDMF || (ui = dmfinfo[dmf]) == 0 || ui->ui_alive == 0) 849 return (ENXIO); 850 sc = &dmfl_softc[dmf]; 851 if (sc->dmfl_state & OPEN) 852 return (EBUSY); 853 addr = (struct dmfdevice *)ui->ui_addr; 854 if (addr->dmfl_ctrl & DMFL_OFFLINE) { 855 #ifdef notdef 856 log(LOG_WARNING, "dmf%d: line printer offline/jammed\n", 857 dmf); 858 #endif 859 return (EIO); 860 } 861 if ((addr->dmfl_ctrl & DMFL_CONV)) { 862 log(LOG_WARNING, "dmf%d: line printer disconnected\n", dmf); 863 return (EIO); 864 } 865 866 addr->dmfl_ctrl = 0; 867 sc->dmfl_state |= OPEN; 868 return (0); 869 } 870 871 /* ARGSUSED */ 872 dmflclose(dev, flag) 873 dev_t dev; 874 int flag; 875 { 876 register int dmf = DMFL_UNIT(dev); 877 register struct dmfl_softc *sc = &dmfl_softc[dmf]; 878 register struct uba_device *ui = dmfinfo[dmf]; 879 880 sc->dmfl_state = 0; 881 if (sc->dmfl_info != 0) 882 ubarelse((int)ui->ui_ubanum, &sc->dmfl_info); 883 884 ((struct dmfdevice *)ui->ui_addr)->dmfl_ctrl = 0; 885 } 886 887 dmflwrite(dev, uio) 888 dev_t dev; 889 struct uio *uio; 890 { 891 register int n; 892 register int error; 893 register struct dmfl_softc *sc; 894 895 sc = &dmfl_softc[DMFL_UNIT(dev)]; 896 if (sc->dmfl_state & ERROR) 897 return (EIO); 898 while (n = (unsigned)uio->uio_resid) { 899 if (n > DMFL_BUFSIZ) { 900 n = DMFL_BUFSIZ; 901 sc->dmfl_state |= MOREIO; 902 } else 903 sc->dmfl_state &= ~MOREIO; 904 if (error = uiomove(sc->dmfl_buf, (int)n, UIO_WRITE, uio)) 905 return (error); 906 if (error = dmflout(dev, sc->dmfl_buf, n)) 907 return (error); 908 } 909 return (0); 910 } 911 912 913 /* 914 * dmflout -- start io operation to dmf line printer 915 * cp is addr of buf of n chars to be sent. 916 * 917 * -- dmf will be put in formatted output mode, this will 918 * be selectable from an ioctl if the 919 * need ever arises. 920 */ 921 dmflout(dev, cp, n) 922 dev_t dev; 923 char *cp; 924 int n; 925 { 926 register struct dmfl_softc *sc; 927 register int dmf; 928 register struct uba_device *ui; 929 register struct dmfdevice *d; 930 int s; 931 932 dmf = DMFL_UNIT(dev); 933 sc = &dmfl_softc[dmf]; 934 if (sc->dmfl_state & ERROR) 935 return (EIO); 936 ui = dmfinfo[dmf]; 937 /* 938 * allocate unibus resources, will be released when io 939 * operation is done. 940 */ 941 if (sc->dmfl_info == 0) 942 sc->dmfl_info = uballoc(ui->ui_ubanum, cp, n, 0); 943 d = (struct dmfdevice *)ui->ui_addr; 944 d->dmfl_ctrl = sc->dmfl_format; /* indir reg 2 */ 945 /* indir reg auto increments on r/w */ 946 /* SO DON'T CHANGE THE ORDER OF THIS CODE */ 947 d->dmfl_indrct = 0; /* prefix chars & num */ 948 d->dmfl_indrct = 0; /* suffix chars & num */ 949 d->dmfl_indrct = sc->dmfl_info; /* dma lo 16 bits addr */ 950 d->dmfl_indrct = -n; /* number of chars */ 951 952 d->dmfl_indrct = ((sc->dmfl_info>>16)&3) | DMFL_OPTIONS; 953 /* dma hi 2 bits addr */ 954 d->dmfl_indrct = sc->dmfl_lines /* lines per page */ 955 | (sc->dmfl_cols<<8); /* carriage width */ 956 sc->dmfl_state |= ASLP; 957 s = spltty(); 958 d->dmfl_ctrl |= DMFL_PEN | DMFL_IE; 959 while (sc->dmfl_state & ASLP) { 960 sleep(sc->dmfl_buf, PZERO + 8); 961 while (sc->dmfl_state & ERROR) { 962 timeout(dmflint, (caddr_t)dmf, 10 * hz); 963 sleep((caddr_t)&sc->dmfl_state, PZERO + 8); 964 } 965 } 966 splx(s); 967 return (0); 968 } 969 970 /* 971 * dmflint -- handle an interrupt from the line printer part of the dmf32 972 */ 973 dmflint(dmf) 974 int dmf; 975 { 976 register struct uba_device *ui; 977 register struct dmfl_softc *sc; 978 register struct dmfdevice *d; 979 short dmfl_stats; 980 981 ui = dmfinfo[dmf]; 982 sc = &dmfl_softc[dmf]; 983 d = (struct dmfdevice *)ui->ui_addr; 984 985 d->dmfl_ctrl &= ~DMFL_IE; 986 dmfl_stats = d->dmfl_ctrl; 987 if (sc->dmfl_state & ERROR) { 988 if ((dmfl_stats & DMFL_OFFLINE) == 0) 989 sc->dmfl_state &= ~ERROR; 990 wakeup((caddr_t)&sc->dmfl_state); 991 return; 992 } 993 if (dmfl_stats & DMFL_DMAERR) 994 log(LOG_WARNING, "dmf%d: NXM\n", dmf); 995 if (dmfl_stats & DMFL_OFFLINE) { 996 log(LOG_WARNING, "dmf%d: printer error\n", dmf); 997 sc->dmfl_state |= ERROR; 998 } 999 #ifdef notdef 1000 if (dmfl_stats & DMFL_PDONE) { 1001 printf("bytes= %d\n", d->dmfl_indrct); 1002 printf("lines= %d\n", d->dmfl_indrct); 1003 } 1004 #endif 1005 sc->dmfl_state &= ~ASLP; 1006 wakeup((caddr_t)sc->dmfl_buf); 1007 if (sc->dmfl_info && (sc->dmfl_state & MOREIO) == 0) 1008 ubarelse(ui->ui_ubanum, &sc->dmfl_info); 1009 } 1010 1011 /* stubs for interrupt routines for devices not yet supported */ 1012 1013 dmfsrint() 1014 { 1015 printf("dmfsrint\n"); 1016 } 1017 1018 dmfsxint() 1019 { 1020 printf("dmfsxint\n"); 1021 } 1022 1023 dmfdaint() 1024 { 1025 printf("dmfdaint\n"); 1026 } 1027 1028 dmfdbint() 1029 { 1030 printf("dmfdbint\n"); 1031 } 1032 #endif NDMF 1033