|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985, 1986 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: * @(#)dmz.c 7.1 (Berkeley) 6/5/86 ! 7: */ ! 8: ! 9: /* ! 10: * DMZ-32 driver ! 11: * HISTORY ! 12: * 23-Apr-85 Joe Camaratta (jcc) at Siemens RTL ! 13: * Driver for DEC's DMZ32 24-line asynchronous multiplexor. ! 14: * Based on Chris Maloney's driver for DEC's DMF32 ! 15: * ! 16: * 9-Aug-85 Mike Meyer (mwm) at ucb ! 17: * Mangled into shape for 4.3. ! 18: */ ! 19: ! 20: #include "dmz.h" ! 21: #if NDMZ > 0 ! 22: ! 23: ! 24: #include "../machine/pte.h" ! 25: ! 26: ! 27: #include "bk.h" ! 28: #include "uba.h" ! 29: #include "param.h" ! 30: #include "conf.h" ! 31: #include "dir.h" ! 32: #include "user.h" ! 33: #include "proc.h" ! 34: #include "ioctl.h" ! 35: #include "tty.h" ! 36: #include "map.h" ! 37: #include "buf.h" ! 38: #include "vm.h" ! 39: #include "bkmac.h" ! 40: #include "clist.h" ! 41: #include "file.h" ! 42: #include "uio.h" ! 43: #include "kernel.h" ! 44: #include "syslog.h" ! 45: ! 46: #include "ubareg.h" ! 47: #include "ubavar.h" ! 48: #include "dmzreg.h" ! 49: #include "dmreg.h" ! 50: ! 51: int dmzprobe(), dmzattach(), dmzrint(), dmzxint(); ! 52: struct uba_device *dmzinfo[NDMZ]; ! 53: u_short dmzstd[] = {0, 0}; ! 54: struct uba_driver dmzdriver = { ! 55: dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo ! 56: }; ! 57: ! 58: #define NDMZLINES (NDMZ*24) ! 59: ! 60: int ttrstrt(); ! 61: struct tty dmz_tty[NDMZLINES]; ! 62: ! 63: int dmzsoftCAR[NDMZ]; ! 64: ! 65: struct { ! 66: char dmz_state; /* dmz state */ ! 67: int dmz_count; /* dmz dma count */ ! 68: } dmz_softc[NDMZ*24]; ! 69: ! 70: #define ST_TXOFF (0x01) /* transmission turned off (^S) */ ! 71: #define ST_DMA (0x02) /* dma inprogress */ ! 72: #define ST_INBUSY (0x04) /* stop transmission in busy */ ! 73: ! 74: char dmz_speeds[] = { ! 75: 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 ! 76: }; ! 77: ! 78: #ifndef PORTSELECTOR ! 79: #define ISPEED B9600 ! 80: #define IFLAGS (EVENP|ODDP|ECHO) ! 81: #else ! 82: #define ISPEED B4800 ! 83: #define IFLAGS (EVENP|ODDP) ! 84: #endif ! 85: ! 86: #ifndef lint ! 87: int ndmz = NDMZLINES; /* Used by pstat/iostat */ ! 88: #endif ! 89: ! 90: short dmzact[NDMZ]; /* Mask of active octets on the dmz */ ! 91: int dmzstart(); ! 92: ! 93: /* ! 94: * SILO_TIMEOUT represents the number of milliseconds characters can sit ! 95: * in the input silo without causing an interrupt. If data overruns or ! 96: * slow XON/XOFF occur, set it lower but AT LEAST equal to 1. ! 97: */ ! 98: #define SILO_TIMEOUT (3) ! 99: ! 100: /* ! 101: * DO_DMA_COUNT represents the threshold of the number of output ! 102: * characters beyond which the driver uses DMA mode. ! 103: */ ! 104: #define DO_DMA_COUNT (10) ! 105: ! 106: #define TRUE (1) ! 107: #define FALSE (0) ! 108: ! 109: int cbase[NUBA]; /* base address in unibus map */ ! 110: int dmz_ubinfo[NUBA]; /* info about allocated unibus map */ ! 111: ! 112: #define UBACVT(x, uban) (cbase[uban] + ((x) - (char *)cfree)) ! 113: ! 114: /* These flags are for debugging purposes only */ ! 115: int dmz_dma_on = 1; ! 116: ! 117: dmzprobe(reg) ! 118: caddr_t reg; ! 119: { ! 120: register int br, cvec; ! 121: register struct dmzdevice *dmz_addr; ! 122: register unsigned int a; ! 123: ! 124: dmz_addr = (struct dmzdevice *)reg; ! 125: ! 126: #ifdef lint ! 127: br = 0; cvec = br; br = cvec; dmzxinta(0); dmzxintb(0); dmzxintc(0); ! 128: dmzrinta(0); dmzrintb(0); dmzrintc(0); ! 129: #endif ! 130: ! 131: br = 0x15; ! 132: ! 133: a = dmz_addr->dmz_config; ! 134: if (((a>>12) & ~DMZ_INTERFACE) != 0) { ! 135: printf(" Unknown interface type\n"); ! 136: return (0); ! 137: } ! 138: if (((a>>8) & DMZ_NOC_MASK) != 3) { ! 139: printf(" Not all octets are available\n"); ! 140: return (0); ! 141: } ! 142: ! 143: cvec = (uba_hd[numuba].uh_lastiv -= 4 * 6); ! 144: dmz_addr->dmz_config = cvec >> 2; ! 145: ! 146: return (sizeof(struct dmzdevice)); ! 147: } ! 148: ! 149: dmzattach(ui) ! 150: struct uba_device *ui; ! 151: { ! 152: dmzsoftCAR[ui->ui_unit] = ui->ui_flags; ! 153: cbase[ui->ui_ubanum] = -1; ! 154: } ! 155: ! 156: /* ARGSUSED */ ! 157: dmzopen(device, flag) ! 158: dev_t device; ! 159: int flag; ! 160: { ! 161: register struct tty *tp; ! 162: register int unit, controller; ! 163: register struct dmzdevice *dmz_addr; ! 164: register struct uba_device *ui; ! 165: int priority; ! 166: int octet; ! 167: ! 168: unit = minor(device); ! 169: controller = DMZ(unit); ! 170: octet = OCTET(unit); ! 171: ! 172: if (unit >= NDMZLINES || ! 173: (ui = dmzinfo[controller]) == 0 || ! 174: ui->ui_alive == 0) ! 175: return (ENXIO); ! 176: ! 177: tp = &dmz_tty[unit]; ! 178: ! 179: if ((tp->t_state & TS_XCLUDE) && u.u_uid != 0) ! 180: return (EBUSY); ! 181: ! 182: dmz_addr = (struct dmzdevice *)ui->ui_addr; ! 183: tp->t_addr = (caddr_t)dmz_addr; ! 184: tp->t_oproc = dmzstart; ! 185: ! 186: /* ! 187: * Set up Unibus map registers. Block uba resets, which can ! 188: * clear the state. ! 189: */ ! 190: priority = spl5(); ! 191: if (cbase[ui->ui_ubanum] == -1) { ! 192: dmz_ubinfo[ui->ui_ubanum] = ! 193: uballoc(ui->ui_ubanum, (caddr_t)cfree, ! 194: nclist * sizeof(struct cblock), 0); ! 195: if (dmz_ubinfo[ui->ui_ubanum] == 0) { ! 196: splx(priority); ! 197: printf("dmz: insufficient unibus map regs\n"); ! 198: return (ENOMEM); ! 199: } ! 200: cbase[ui->ui_ubanum] = UBAI_ADDR(dmz_ubinfo[ui->ui_ubanum]); ! 201: } ! 202: ! 203: if ((dmzact[controller] & (1 << octet)) == 0) { ! 204: dmz_addr->octet[octet].octet_csr |= DMZ_IE; ! 205: dmzact[controller] |= 1 << octet; ! 206: dmz_addr->octet[octet].octet_receive.octet_sato = SILO_TIMEOUT; ! 207: } ! 208: ! 209: splx(priority); ! 210: ! 211: if ((tp->t_state & TS_ISOPEN) == 0) { ! 212: ttychars(tp); ! 213: #ifndef PORTSELECTOR ! 214: if (tp->t_ispeed == 0) { ! 215: #else ! 216: tp->t_state |= TS_HUPCLS; ! 217: #endif PORTSELECTOR ! 218: tp->t_ispeed = ISPEED; ! 219: tp->t_ospeed = ISPEED; ! 220: tp->t_flags = IFLAGS; ! 221: #ifndef PORTSELECTOR ! 222: } ! 223: #endif PORTSELECTOR ! 224: dmz_softc[unit].dmz_state = 0; ! 225: } ! 226: dmzparam(unit); ! 227: ! 228: /* ! 229: * Wait for carrier, then process line discipline specific open. ! 230: */ ! 231: if ((dmzmctl(unit, DMZ_ON, DMSET) & DMZ_CAR) || ! 232: (dmzsoftCAR[controller] & (1 << (unit % 24)))) ! 233: tp->t_state |= TS_CARR_ON; ! 234: priority = spl5(); ! 235: while ((tp->t_state & TS_CARR_ON) == 0) { ! 236: tp->t_state |= TS_WOPEN; ! 237: sleep((caddr_t) &tp->t_rawq, TTIPRI); ! 238: } ! 239: splx(priority); ! 240: ! 241: return ((*linesw[tp->t_line].l_open)(device, tp)); ! 242: } ! 243: ! 244: dmzparam(unit) ! 245: register int unit; ! 246: { ! 247: register struct tty *tp; ! 248: register struct dmzdevice *dmz_addr; ! 249: register int line_parameters; ! 250: register int octet; ! 251: int priority; ! 252: ! 253: octet = OCTET(unit); ! 254: ! 255: tp = &dmz_tty[unit]; ! 256: dmz_addr = (struct dmzdevice *)tp->t_addr; ! 257: ! 258: priority = spl5(); ! 259: if ((tp->t_ispeed) == 0) { ! 260: tp->t_state |= TS_HUPCLS; ! 261: (void) dmzmctl(unit, DMZ_OFF, DMSET); ! 262: splx(priority); ! 263: return; ! 264: } ! 265: ! 266: line_parameters = (dmz_speeds[tp->t_ospeed] << 12) | (dmz_speeds[tp->t_ispeed] << 8); ! 267: ! 268: if ((tp->t_ispeed) == B134) ! 269: line_parameters |= DMZ_6BT | DMZ_PEN; ! 270: else if (tp->t_flags & (RAW | LITOUT | PASS8)) ! 271: line_parameters |= DMZ_8BT; ! 272: else ! 273: line_parameters |= DMZ_7BT | DMZ_PEN; ! 274: ! 275: if (tp->t_flags & EVENP) ! 276: line_parameters |= DMZ_EPR; ! 277: if ((tp->t_ospeed) == B110) ! 278: line_parameters |= DMZ_SCD; ! 279: ! 280: line_parameters |= (unit & 07); ! 281: ! 282: dmz_addr->octet[octet].octet_lprm = line_parameters; ! 283: splx(priority); ! 284: } ! 285: ! 286: /* ARGSUSED */ ! 287: dmzclose(device, flag) ! 288: dev_t device; ! 289: int flag; ! 290: { ! 291: register struct tty *tp; ! 292: register int unit; ! 293: ! 294: unit = minor(device); ! 295: tp = &dmz_tty[unit]; ! 296: (*linesw[tp->t_line].l_close)(tp); ! 297: ! 298: /* ! 299: * Clear break, hang-up and close the modem. ! 300: */ ! 301: (void) dmzmctl(unit, DMZ_BRK, DMBIC); ! 302: if (tp->t_state & TS_HUPCLS || (tp->t_state & TS_ISOPEN) == 0) ! 303: (void) dmzmctl(unit, DMZ_OFF, DMSET); ! 304: ttyclose(tp); ! 305: return; ! 306: } ! 307: ! 308: dmzreset(uban) ! 309: int uban; ! 310: { ! 311: register int controller, unit; ! 312: register struct tty *tp; ! 313: register struct uba_device *ui; ! 314: register struct dmzdevice *dmz_addr; ! 315: int i; ! 316: int octet; ! 317: ! 318: for (controller = 0; controller < NDMZ; controller++) { ! 319: ui = dmzinfo[controller]; ! 320: if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) ! 321: continue; ! 322: printf("dmz%d ", controller); ! 323: dmz_addr = (struct dmzdevice *) ui->ui_addr; ! 324: ! 325: if (dmz_ubinfo[uban]) { ! 326: dmz_ubinfo[uban] = uballoc(uban, (caddr_t)cfree, ! 327: nclist * sizeof(struct cblock), 0); ! 328: cbase[uban] = UBAI_ADDR(dmz_ubinfo[uban]); ! 329: } ! 330: ! 331: for (octet = 0; octet < 3; octet++) ! 332: if ((dmzact[controller] & (1 << octet)) != 0) { ! 333: dmz_addr->octet[octet].octet_csr |= DMZ_IE; ! 334: dmz_addr->octet[octet].octet_receive.octet_sato = SILO_TIMEOUT; ! 335: } ! 336: ! 337: unit = controller * 24; ! 338: ! 339: /* ! 340: * If a unit is open or waiting for open to complete, ! 341: * reset it. ! 342: */ ! 343: for (i = 0; i < 24; i++) { ! 344: dmz_softc[unit].dmz_state = 0; ! 345: tp = &dmz_tty[unit]; ! 346: if (tp->t_state & (TS_ISOPEN | TS_WOPEN)) { ! 347: dmzparam(unit); ! 348: (void) dmzmctl(unit, DMZ_ON, DMSET); ! 349: tp->t_state &= ~TS_BUSY; ! 350: dmzstart(tp); ! 351: } ! 352: unit++; ! 353: } ! 354: } ! 355: return; ! 356: } ! 357: ! 358: dmzread(device, uio) ! 359: dev_t device; ! 360: struct uio *uio; ! 361: { ! 362: register struct tty *tp; ! 363: int xstatus; ! 364: ! 365: tp = &dmz_tty[minor(device)]; ! 366: xstatus = (*linesw[tp->t_line].l_read)(tp, uio); ! 367: return (xstatus); ! 368: } ! 369: ! 370: dmzwrite(device, uio) ! 371: dev_t device; ! 372: struct uio *uio; ! 373: { ! 374: register struct tty *tp; ! 375: int xstatus; ! 376: ! 377: tp = &dmz_tty[minor(device)]; ! 378: xstatus = (*linesw[tp->t_line].l_write)(tp, uio); ! 379: return (xstatus); ! 380: } ! 381: ! 382: dmzrinta(controller) ! 383: int controller; ! 384: { ! 385: dmzrint(controller, 0); ! 386: } ! 387: ! 388: dmzrintb(controller) ! 389: int controller; ! 390: { ! 391: dmzrint(controller, 1); ! 392: } ! 393: ! 394: dmzrintc(controller) ! 395: int controller; ! 396: { ! 397: dmzrint(controller, 2); ! 398: } ! 399: ! 400: dmzrint(controller, octet) ! 401: int controller; ! 402: register int octet; ! 403: { ! 404: register struct tty *tp; ! 405: register int character; ! 406: register struct dmzdevice *dmz_addr; ! 407: register struct tty *tp0; ! 408: register int unit; ! 409: register struct uba_device *ui; ! 410: int overrun; ! 411: ! 412: overrun = 0; ! 413: ui = dmzinfo[controller]; ! 414: if (ui == 0 || ui->ui_alive == 0) ! 415: return; ! 416: dmz_addr = (struct dmzdevice *) ui->ui_addr; ! 417: tp0 = &dmz_tty[controller * 24]; ! 418: ! 419: while ((character = dmz_addr->octet[octet].octet_receive.octet_rb) < 0) { ! 420: unit = (character >> 8) & 07; /* unit is bits 8-10 of rb */ ! 421: tp = tp0 + (octet * 8 + unit); ! 422: ! 423: if (character & DMZ_DSC) { ! 424: dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_RMSTSC | unit; ! 425: if (dmz_addr->octet[octet].octet_rmstsc & DMZ_CAR) ! 426: (void)(*linesw[tp->t_line].l_modem)(tp, 1); ! 427: else if ((dmzsoftCAR[controller] & ! 428: (1 << (octet * 8 + unit))) == 0 && ! 429: (*linesw[tp->t_line].l_modem)(tp, 0) == 0) ! 430: (void)dmzmctl(tp - dmz_tty, DMZ_OFF, DMSET); ! 431: continue; ! 432: } ! 433: ! 434: if ((tp->t_state&TS_ISOPEN)==0) { ! 435: wakeup((caddr_t)&tp->t_rawq); ! 436: #ifdef PORTSELECTOR ! 437: if ((tp->t_state&TS_WOPEN) == 0) ! 438: #endif ! 439: continue; ! 440: } ! 441: ! 442: if (character & DMZ_PE) { ! 443: if ((tp->t_flags & (EVENP | ODDP)) == EVENP || ! 444: (tp->t_flags & (EVENP | ODDP)) == ODDP) ! 445: continue; ! 446: } ! 447: ! 448: if ((character & DMZ_DO) && overrun == 0) { ! 449: log(LOG_WARNING, "dmz%d: silo overflow\n", controller); ! 450: overrun = 1; ! 451: } ! 452: ! 453: if (character & DMZ_FE) { ! 454: if (tp->t_flags & RAW) ! 455: character = 0; ! 456: else ! 457: character = tp->t_intrc; ! 458: } ! 459: ! 460: (*linesw[tp->t_line].l_rint)(character, tp); ! 461: } ! 462: ! 463: return; ! 464: } ! 465: ! 466: dmzxinta(controller) ! 467: int controller; ! 468: { ! 469: dmzxint(controller, 0); ! 470: } ! 471: ! 472: dmzxintb(controller) ! 473: int controller; ! 474: { ! 475: dmzxint(controller, 1); ! 476: } ! 477: ! 478: dmzxintc(controller) ! 479: int controller; ! 480: { ! 481: dmzxint(controller, 2); ! 482: } ! 483: ! 484: dmzxint(controller, octet) ! 485: int controller; ! 486: register int octet; ! 487: { ! 488: register struct tty *tp; ! 489: register struct dmzdevice *dmz_addr; ! 490: register struct uba_device *ui; ! 491: register int unit, t; ! 492: int priority; ! 493: ! 494: ui = dmzinfo[controller]; ! 495: dmz_addr = (struct dmzdevice *)ui->ui_addr; ! 496: ! 497: priority = spl5(); ! 498: ! 499: while ((t = dmz_addr->octet[octet].octet_csr) & DMZ_TRDY) { ! 500: unit = controller * 24 + (octet * 8 + ((t>>8) & 07)); ! 501: tp = &dmz_tty[unit]; ! 502: tp->t_state &= ~TS_BUSY; ! 503: ! 504: if (t & DMZ_NXM) ! 505: printf("dmz%d: NXM line %d\n", controller, ! 506: octet * 8 + (unit & 07)); ! 507: ! 508: if (tp->t_state & TS_FLUSH) { ! 509: tp->t_state &= ~TS_FLUSH; ! 510: dmz_addr->octet[octet].octet_csr = ! 511: DMZ_IE | IR_LCTMR | (unit & 07); ! 512: dmz_addr->octet[octet].octet_lctmr = ! 513: (dmz_addr->octet[octet].octet_lctmr | DMZ_TE); ! 514: } else ! 515: if (dmz_softc[unit].dmz_state & ST_DMA) ! 516: ndflush(&tp->t_outq, dmz_softc[unit].dmz_count); ! 517: dmz_softc[unit].dmz_state = 0; ! 518: ! 519: if (tp->t_line) ! 520: (*linesw[tp->t_line].l_start)(tp); ! 521: else ! 522: dmzstart(tp); ! 523: } ! 524: ! 525: splx(priority); ! 526: return; ! 527: } ! 528: ! 529: dmzstart(tp) ! 530: register struct tty *tp; ! 531: { ! 532: register struct dmzdevice *dmz_addr; ! 533: register int unit, nch, room; ! 534: int controller, octet; ! 535: int priority, car, use_dma; ! 536: register int i; ! 537: register char *cp; ! 538: ! 539: unit = minor(tp->t_dev); ! 540: controller = DMZ(unit); ! 541: octet = OCTET(unit); ! 542: dmz_addr = (struct dmzdevice *)tp->t_addr; ! 543: ! 544: priority = spl5(); ! 545: ! 546: if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) ! 547: goto out; ! 548: ! 549: /* ! 550: * If the transmitter has been disabled, reenable it. ! 551: * If the transmitter was disabled before the xint (the ! 552: * ST_INBUSY was still on), then reset the BUSY state and ! 553: * we will wait for the interrupt. If !TS_BUSY, we already ! 554: * saw the interrupt so we can start another transmission. ! 555: */ ! 556: if (dmz_softc[unit].dmz_state & ST_TXOFF) { ! 557: dmz_addr->octet[octet].octet_csr = ! 558: DMZ_IE | IR_LCTMR | (unit & 07); ! 559: dmz_addr->octet[octet].octet_lctmr = ! 560: (dmz_addr->octet[octet].octet_lctmr | DMZ_TE); ! 561: dmz_softc[unit].dmz_state &= ~ST_TXOFF; ! 562: if (dmz_softc[unit].dmz_state & ST_INBUSY) { ! 563: dmz_softc[unit].dmz_state &= ~ST_INBUSY; ! 564: tp->t_state |= TS_BUSY; ! 565: goto out; ! 566: } ! 567: } ! 568: ! 569: if (tp->t_outq.c_cc <= TTLOWAT(tp)) { ! 570: if (tp->t_state & TS_ASLEEP) { ! 571: tp->t_state &= ~TS_ASLEEP; ! 572: wakeup((caddr_t)&tp->t_outq); ! 573: } ! 574: if (tp->t_wsel) { ! 575: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); ! 576: tp->t_wsel = 0; ! 577: tp->t_state &= ~TS_WCOLL; ! 578: } ! 579: } ! 580: ! 581: if (tp->t_outq.c_cc == 0) ! 582: goto out; ! 583: if (tp->t_flags & (RAW | LITOUT)) ! 584: nch = ndqb(&tp->t_outq, 0); ! 585: else { ! 586: nch = ndqb(&tp->t_outq, 0200); ! 587: if (nch == 0) { ! 588: nch = getc(&tp->t_outq); ! 589: timeout(ttrstrt, (caddr_t)tp, (nch & 0x7f)+6); ! 590: tp->t_state |= TS_TIMEOUT; ! 591: goto out; ! 592: } ! 593: } ! 594: ! 595: /* ! 596: * Should we use DMA or SILO mode? ! 597: * If nch is greater than DO_DMA_COUNT then DMA. ! 598: */ ! 599: if (nch) { ! 600: dmz_addr->octet[octet].octet_csr = ! 601: DMZ_IE | IR_LCTMR | (unit & 07); ! 602: dmz_addr->octet[octet].octet_lctmr = ! 603: (dmz_addr->octet[octet].octet_lctmr | DMZ_TE); ! 604: tp->t_state |= TS_BUSY; ! 605: ! 606: use_dma = FALSE; ! 607: room = DMZ_SIZ; ! 608: ! 609: if (nch > DO_DMA_COUNT) ! 610: use_dma = TRUE; ! 611: ! 612: if (use_dma && dmz_dma_on) { ! 613: car = UBACVT(tp->t_outq.c_cf, ! 614: dmzinfo[controller]->ui_ubanum); ! 615: dmz_softc[unit].dmz_count = nch; ! 616: dmz_softc[unit].dmz_state |= ST_DMA; ! 617: dmz_addr->octet[octet].octet_csr = ! 618: DMZ_IE | IR_TBA | (unit & 07); ! 619: dmz_addr->octet[octet].octet_tba = car; ! 620: dmz_addr->octet[octet].octet_tcc = ! 621: ((car >> 2) & 0xc000) | nch; ! 622: } else { ! 623: dmz_softc[unit].dmz_state &= ~ST_DMA; ! 624: cp = tp->t_outq.c_cf; ! 625: nch = MIN(nch, room); ! 626: dmz_addr->octet[octet].octet_csr = ! 627: DMZ_IE | IR_TBUF | (unit & 07); ! 628: for (i = 0; i < nch; i++) ! 629: dmz_addr->octet[octet].octet_tbf = *cp++ ; ! 630: ndflush(&tp->t_outq, nch); ! 631: } ! 632: } ! 633: ! 634: out: ! 635: splx(priority); ! 636: return; ! 637: } ! 638: ! 639: /* ARGSUSED */ ! 640: dmzstop(tp, flag) ! 641: register struct tty *tp; ! 642: { ! 643: register struct dmzdevice *dmz_addr; ! 644: register int unit, priority, octet; ! 645: ! 646: priority = spl5(); ! 647: dmz_addr = (struct dmzdevice *) tp->t_addr; ! 648: unit = minor(tp->t_dev); ! 649: octet = OCTET(unit); ! 650: ! 651: dmz_addr->octet[octet].octet_csr = IR_LCTMR | (unit & 07) | DMZ_IE; ! 652: dmz_addr->octet[octet].octet_lctmr = ! 653: (dmz_addr->octet[octet].octet_lctmr & ~DMZ_TE); ! 654: dmz_softc[unit].dmz_state |= ST_TXOFF; ! 655: if ((tp->t_state & TS_TTSTOP) == 0) { ! 656: tp->t_state |= (TS_FLUSH | TS_BUSY); ! 657: dmz_addr->octet[octet].octet_lctmr = ! 658: (dmz_addr->octet[octet].octet_lctmr | DMZ_FLS); ! 659: } else if (tp->t_state & TS_BUSY) { ! 660: dmz_softc[unit].dmz_state |= ST_INBUSY; ! 661: tp->t_state &= ~TS_BUSY; ! 662: } ! 663: ! 664: splx(priority); ! 665: return; ! 666: } ! 667: ! 668: /* ARGSUSED */ ! 669: dmzioctl(device, command, data, flag) ! 670: dev_t device; ! 671: caddr_t data; ! 672: { ! 673: register struct tty *tp; ! 674: register int unit; ! 675: int error; ! 676: ! 677: unit = minor(device); ! 678: tp = &dmz_tty[unit]; ! 679: ! 680: error = (*linesw[tp->t_line].l_ioctl)(tp, command, data, flag); ! 681: if (error >= 0) ! 682: return (error); ! 683: error = ttioctl(tp, command, data, flag); ! 684: if (error >= 0) { ! 685: if (command == TIOCSETP || command == TIOCSETN || ! 686: command == TIOCLSET || command == TIOCLBIS || ! 687: command == TIOCLBIC) ! 688: dmzparam(unit); ! 689: return (error); ! 690: } ! 691: ! 692: switch (command) { ! 693: case TIOCSBRK: ! 694: (void) dmzmctl(unit, DMZ_BRK, DMBIS); ! 695: break; ! 696: case TIOCCBRK: ! 697: (void) dmzmctl(unit, DMZ_BRK, DMBIC); ! 698: break; ! 699: case TIOCSDTR: ! 700: (void) dmzmctl(unit, DMZ_DTR | DMZ_RTS, DMBIS); ! 701: break; ! 702: case TIOCCDTR: ! 703: (void) dmzmctl(unit, DMZ_DTR | DMZ_RTS, DMBIC); ! 704: break; ! 705: case TIOCMSET: ! 706: (void) dmzmctl(unit, dmtodmz(*(int *)data), DMSET); ! 707: break; ! 708: case TIOCMBIS: ! 709: (void) dmzmctl(unit, dmtodmz(*(int *)data), DMBIS); ! 710: break; ! 711: case TIOCMBIC: ! 712: (void) dmzmctl(unit, dmtodmz(*(int *)data), DMBIC); ! 713: break; ! 714: case TIOCMGET: ! 715: *(int *)data = dmzmctl(unit, 0, DMGET); ! 716: break; ! 717: default: ! 718: return (ENOTTY); ! 719: } ! 720: return (0); ! 721: } ! 722: ! 723: dmzmctl(unit, bits, how) ! 724: register int unit; ! 725: int bits, how; ! 726: { ! 727: register struct dmzdevice *dmz_addr; ! 728: register int modem_status, line_control; ! 729: int priority; ! 730: int octet; ! 731: ! 732: octet = OCTET(unit); ! 733: dmz_addr = (struct dmzdevice *) dmzinfo[DMZ(unit)]->ui_addr; ! 734: ! 735: priority = spl5(); ! 736: dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_RMSTSC | (unit & 07); ! 737: modem_status = dmz_addr->octet[octet].octet_rmstsc & 0xff00; ! 738: ! 739: dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_LCTMR | (unit & 07); ! 740: line_control = dmz_addr->octet[octet].octet_lctmr; ! 741: ! 742: ! 743: switch (how) { ! 744: case DMSET: ! 745: line_control = bits; ! 746: break; ! 747: case DMBIS: ! 748: line_control |= bits; ! 749: break; ! 750: case DMBIC: ! 751: line_control &= ~bits; ! 752: break; ! 753: case DMGET: ! 754: (void) splx(priority); ! 755: return (dmztodm(modem_status, line_control)); ! 756: } ! 757: ! 758: dmz_addr->octet[octet].octet_csr = ! 759: DMZ_IE | IR_LCTMR | (unit & 07); ! 760: dmz_addr->octet[octet].octet_lctmr = line_control; ! 761: ! 762: splx(priority); ! 763: return (modem_status); ! 764: } ! 765: ! 766: /* ! 767: * Routine to convert modem status from dm to dmz lctmr format. ! 768: */ ! 769: dmtodmz(bits) ! 770: register int bits; ! 771: { ! 772: register int lcr = DMZ_LCE; ! 773: ! 774: if (bits & DML_DTR) ! 775: lcr |= DMZ_DTR; ! 776: if (bits & DML_RTS) ! 777: lcr |= DMZ_RTS; ! 778: if (bits & DML_ST) ! 779: lcr |= DMF_ST; ! 780: if (bits & DML_USR) ! 781: lcr |= DMZ_USRW; ! 782: return (lcr); ! 783: } ! 784: ! 785: /* ! 786: * Routine to convert modem status from dmz receive modem status ! 787: * and line control register to dm format. ! 788: * If dmz user modem read bit set, set DML_USR. ! 789: */ ! 790: dmztodm(rms, lcr) ! 791: register int rms, lcr; ! 792: { ! 793: ! 794: rms = ((rms & (DMZ_DSR|DMZ_RNG|DMZ_CAR|DMZ_CTS|DMF_SR)) >> 7) | ! 795: ((rms & DMZ_USRR) >> 1) | DML_LE; ! 796: if (lcr & DMZ_DTR) ! 797: rms |= DML_DTR; ! 798: if (lcr & DMF_ST) ! 799: rms |= DML_ST; ! 800: if (lcr & DMZ_RTS) ! 801: rms |= DML_RTS; ! 802: return (rms); ! 803: } ! 804: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.