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

Defined functions

dmtodmz defined in line 769; used 3 times
dmzattach defined in line 149; used 2 times
dmzclose defined in line 287; never used
dmzioctl defined in line 669; never used
dmzmctl defined in line 723; used 14 times
dmzopen defined in line 157; never used
dmzparam defined in line 244; used 3 times
dmzprobe defined in line 117; used 2 times
dmzread defined in line 358; never used
dmzreset defined in line 308; never used
dmzrint defined in line 400; used 4 times
dmzrinta defined in line 382; used 2 times
dmzrintb defined in line 388; used 2 times
dmzrintc defined in line 394; used 2 times
dmzstart defined in line 529; used 4 times
dmzstop defined in line 640; never used
dmztodm defined in line 790; used 1 times
dmzwrite defined in line 370; never used
dmzxint defined in line 484; used 4 times
dmzxinta defined in line 466; used 2 times
dmzxintb defined in line 472; used 2 times
dmzxintc defined in line 478; used 2 times

Defined variables

cbase defined in line 109; used 5 times
dmz_dma_on defined in line 115; used 1 times
dmz_speeds defined in line 74; used 2 times
  • in line 266(2)
dmz_tty defined in line 61; used 10 times
dmz_ubinfo defined in line 110; used 6 times
dmzact defined in line 90; used 3 times
dmzdriver defined in line 54; used 1 times
dmzinfo defined in line 52; used 7 times
dmzsoftCAR defined in line 63; used 3 times
dmzstd defined in line 53; used 1 times
  • in line 55
ndmz defined in line 87; never used

Defined macros

DO_DMA_COUNT defined in line 104; used 1 times
FALSE defined in line 107; used 1 times
IFLAGS defined in line 83; used 1 times
ISPEED defined in line 82; used 2 times
NDMZLINES defined in line 58; used 3 times
SILO_TIMEOUT defined in line 98; used 2 times
ST_DMA defined in line 71; used 3 times
ST_INBUSY defined in line 72; used 3 times
ST_TXOFF defined in line 70; used 3 times
TRUE defined in line 106; used 1 times
UBACVT defined in line 112; used 1 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3139
Valid CSS Valid XHTML 1.0 Strict