1: /*
   2:  *	SCCS id	@(#)dh.c	2.1 (Berkeley)	11/20/83
   3:  */
   4: 
   5: #include "dh.h"
   6: #if NDH > 0
   7: #include "param.h"
   8: #include <sys/conf.h>
   9: #include <sys/systm.h>
  10: #include <sys/dir.h>
  11: #include <sys/user.h>
  12: #include <sys/file.h>
  13: #include <sys/tty.h>
  14: #include <sys/dhreg.h>
  15: #include <sys/uba.h>
  16: 
  17: #define q3  tp->t_outq
  18: 
  19: #if defined (UNIBUS_MAP) || defined (UCB_CLIST)
  20: extern  ubadr_t clstaddr;
  21: #ifdef  UCB_CLIST
  22: extern  struct  cblock  *cfree;
  23: #else   UCB_CLIST
  24: extern  struct  cblock  cfree[];
  25: #endif	UCB_CLIST
  26: #define cpaddr(x)   (clstaddr + (ubadr_t)((x) - cfree))
  27: 
  28: #else   defined (UNIBUS_MAP) || defined (UCB_CLIST)
  29: #define cpaddr(x)   (x)
  30: #endif	defined (UNIBUS_MAP) || defined (UCB_CLIST)
  31: 
  32: #ifdef  DH_SOFTCAR
  33: #define DHLINE(dev) (minor(dev) & 0177)
  34: #else
  35: #define DHLINE(dev) minor(dev)
  36: #endif
  37: 
  38: #define NDHLINE (NDH * 16)
  39: struct  tty dh11[NDHLINE];
  40: int ndh11   = NDHLINE; /* only for pstat */
  41: int dhlowdm = LOWDM;
  42: int dhndm   = NDM * 16;
  43: int dhstart();
  44: int ttrstrt();
  45: #ifdef  DH_SILO
  46: #define SILOSCANRATE    (hz / 10)
  47: int dhchars[NDH];
  48: void    dhtimer();
  49: #endif	DH_SILO
  50: 
  51: struct  dhdevice *dh_addr[NDH];
  52: #if NDM > 0
  53: struct  dmdevice *dm_addr[NDM];
  54: #endif	NDM
  55: 
  56: /*
  57:  * Software copy of last dhbar
  58:  */
  59: int dhsar[NDH];
  60: 
  61: dhattach(addr, unit)
  62: struct dhdevice *addr;
  63: {
  64:     if ((unsigned) unit >= NDH)
  65:         return 0;
  66:     dh_addr[unit] = addr;
  67:     return 1;
  68: }
  69: 
  70: /*
  71:  * Open a DH line.  Turn on this dh if this is
  72:  * the first use of it.  Also do a dmopen to wait for carrier.
  73:  */
  74: /*ARGSUSED*/
  75: dhopen(dev, flag)
  76: dev_t   dev;
  77: {
  78:     register struct tty *tp;
  79:     register unit;
  80:     register struct dhdevice *addr;
  81: #ifdef  DH_SILO
  82:     static  dh_timer;
  83: #endif	DH_SILO
  84: 
  85:     unit = DHLINE(dev);
  86:     if ((unit >= NDHLINE) || ((addr = dh_addr[unit >> 4]) == 0)) {
  87:         u.u_error = ENXIO;
  88:         return;
  89:     }
  90:     tp = &dh11[unit];
  91:     if (tp->t_state & XCLUDE && u.u_uid != 0) {
  92:         u.u_error = EBUSY;
  93:         return;
  94:     }
  95:     tp->t_addr = (caddr_t) addr;
  96:     tp->t_oproc = dhstart;
  97:     tp->t_iproc = NULL;
  98:     tp->t_state |= WOPEN;
  99: 
 100: #ifdef  DH_SILO
 101:     if (!dh_timer) {
 102:         dh_timer++;
 103:         timeout(dhtimer, (caddr_t) 0, SILOSCANRATE);
 104:     }
 105: #endif	DH_SILO
 106: 
 107:     addr->un.dhcsr |= DH_IE;
 108:     /*
 109: 	 * If this is first open, initialize tty state to default.
 110: 	 */
 111:     if ((tp->t_state & ISOPEN) == 0) {
 112:         ttychars(tp);
 113:         if (tp->t_ispeed == 0) {
 114:             tp->t_ispeed = B300;
 115:             tp->t_ospeed = B300;
 116:             tp->t_flags = ODDP | EVENP | ECHO;
 117:         }
 118:         tp->t_line = DFLT_LDISC;
 119:         dhparam(unit);
 120:     }
 121: #if NDM > 0
 122:     dmopen(dev);
 123: #else
 124:     tp->t_state |= CARR_ON;
 125: #endif
 126:     ttyopen(dev,tp);
 127: }
 128: 
 129: /*
 130:  * Close a DH line, turning off the DM11.
 131:  */
 132: /*ARGSUSED*/
 133: dhclose(dev, flag)
 134: dev_t   dev;
 135: int flag;
 136: {
 137:     register struct tty *tp;
 138:     register unit;
 139: 
 140:     unit = DHLINE(dev);
 141:     tp = &dh11[unit];
 142:     ((struct dhdevice *) (tp->t_addr))->dhbreak &= ~(1 << (unit & 017));
 143: #if NDM > 0
 144:     if (tp->t_state & HUPCLS)
 145:         dmctl(unit, DML_OFF, DMSET);
 146: #endif
 147:     ttyclose(tp);
 148: }
 149: 
 150: /*
 151:  * Read from a DH line.
 152:  */
 153: dhread(dev)
 154: dev_t   dev;
 155: {
 156:     register struct tty *tp;
 157: 
 158:     tp = &dh11[DHLINE(dev)];
 159:     (void) (*linesw[tp->t_line].l_read)(tp);
 160: }
 161: 
 162: /*
 163:  * Write on a DH line.
 164:  */
 165: dhwrite(dev)
 166: {
 167:     register struct tty *tp;
 168: 
 169:     tp = &dh11[DHLINE(dev)];
 170:     (void) (*linesw[tp->t_line].l_write)(tp);
 171: }
 172: 
 173: /*
 174:  * DH11 receiver interrupt.
 175:  */
 176: dhrint(dh)
 177: int dh;
 178: {
 179:     register struct tty *tp;
 180:     register int c;
 181:     register struct dhdevice *addr;
 182:     struct  tty *tp0;
 183:     int overrun = 0;
 184: 
 185:     addr = dh_addr[dh];
 186:     tp0 = &dh11[dh << 4];
 187:     /*
 188: 	 * Loop fetching characters from the silo for this
 189: 	 * dh until there are no more in the silo.
 190: 	 */
 191:     while ((c = addr->dhrcr) < 0) {
 192:         tp = tp0 + ((c >> 8) & 017);
 193:         if (tp >= &dh11[NDHLINE])
 194:             continue;
 195:         if((tp->t_state & ISOPEN) == 0) {
 196:             wakeup((caddr_t)tp);
 197:             continue;
 198:         }
 199: #ifdef  DH_SILO
 200:         dhchars[dh]++;
 201: #endif	DH_SILO
 202: #ifdef  TEXAS_AUTOBAUD
 203:         if (image_mode(tp))
 204:             c &= ~(DH_PE|DH_FE);
 205: #endif
 206:         if (c & DH_PE)
 207:             if ((tp->t_flags & (EVENP | ODDP)) == EVENP
 208:              || (tp->t_flags & (EVENP | ODDP)) == ODDP)
 209:                 continue;
 210:         if ((c & DH_DO) && overrun == 0) {
 211:             printf("dh%d: silo overflow\n", dh);
 212:             overrun = 1;
 213:             }
 214:         if (c & DH_FE)
 215:             /*
 216: 			 * At framing error (break) generate
 217: 			 * a null (in raw mode, for getty), or an
 218: 			 * interrupt (in cooked/cbreak mode).
 219: 			 */
 220:             if (tp->t_flags & RAW)
 221:                 c = 0;
 222:             else
 223:                 c = tun.t_intrc;
 224:         (*linesw[tp->t_line].l_input)(c,tp);
 225:     }
 226: }
 227: 
 228: /*
 229:  * Ioctl for DH11.
 230:  */
 231: dhioctl(dev, cmd, addr, flag)
 232: dev_t   dev;
 233: caddr_t addr;
 234: {
 235:     register struct tty *tp;
 236:     register unit = DHLINE(dev);
 237: 
 238:     tp = &dh11[unit];
 239:     switch (ttioctl(tp, cmd, addr, flag)) {
 240:         case TIOCSETP:
 241:         case TIOCSETN:
 242:         dhparam(unit);
 243:         break;
 244: #ifdef  DH_IOCTL
 245:         case TIOCSBRK:
 246:         ((struct dhdevice *)(tp->t_addr))->dhbreak |= 1 << (unit & 017);
 247:         break;
 248:         case TIOCCBRK:
 249:         ((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
 250:         break;
 251: #if NDM > 0
 252:         case TIOCSDTR:
 253:         dmctl (unit, DML_DTR | DML_RTS, DMBIS);
 254:         break;
 255:         case TIOCCDTR:
 256:         dmctl (unit, DML_DTR | DML_RTS, DMBIC);
 257:         break;
 258: #endif
 259: #endif	DH_IOCTL
 260:         case 0:
 261:         break;
 262:         default:
 263:         u.u_error = ENOTTY;
 264:     }
 265: }
 266: 
 267: /*
 268:  * Set parameters from open or stty into the DH hardware
 269:  * registers.
 270:  */
 271: dhparam(unit)
 272: int unit;
 273: {
 274:     register struct tty *tp;
 275:     register struct dhdevice *addr;
 276:     int s;
 277:     register lpar;
 278: 
 279:     tp = &dh11[unit];
 280:     addr = (struct dhdevice *) tp->t_addr;
 281:     /*
 282: 	 * Block interrupts so parameters will be set
 283: 	 * before the line interrupts.
 284: 	 */
 285:     s = spl5();
 286:     addr->un.dhcsrl = (unit & 017) | DH_IE;
 287:     if ((tp->t_ispeed) == 0) {
 288:         tp->t_state |= HUPCLS;
 289: #if NDM > 0
 290:         dmctl(unit, DML_OFF, DMSET);
 291: #endif
 292:         return;
 293:     }
 294:     lpar = ((tp->t_ospeed) << 10) | ((tp->t_ispeed) << 6);
 295:     if ((tp->t_ispeed) == B134)
 296:         lpar |= BITS6 | PENABLE | HDUPLX;
 297:     else
 298: #ifdef  UCB_NTTY
 299:         if ((tp->t_flags & RAW) || (tp->t_local & LLITOUT))
 300: #else
 301:         if (tp->t_flags & RAW)
 302: #endif
 303:             lpar |= BITS8;
 304:         else
 305:             lpar |= BITS7 | PENABLE;
 306:     if ((tp->t_flags & EVENP) == 0)
 307:         lpar |= OPAR;
 308:     if (tp->t_ospeed == B110)   /* 110 baud */
 309:         lpar |= TWOSB;
 310:     addr->dhlpr = lpar;
 311:     splx(s);
 312: }
 313: 
 314: /*
 315:  * DH transmitter interrupt.
 316:  * Restart each line which used to be active but has
 317:  * terminated transmission since the last interrupt.
 318:  */
 319: dhxint(dh)
 320: int dh;
 321: {
 322:     register struct tty *tp;
 323:     register struct dhdevice *addr;
 324:     register unit;
 325:     int ttybit, bar, *sbar;
 326: 
 327:     addr = dh_addr[dh];
 328:     if (addr->un.dhcsr & DH_NXM) {
 329:         addr->un.dhcsr |= DH_CNI;
 330:         printf("dh%d:  NXM\n", dh);
 331:     }
 332:     sbar = &dhsar[dh];
 333:     bar = *sbar & ~addr->dhbar;
 334:     unit = dh << 4; ttybit = 1;
 335:     addr->un.dhcsr &= ~DH_TI;
 336: 
 337:     for(; bar; unit++, ttybit <<= 1) {
 338:         if(bar & ttybit) {
 339:             *sbar &= ~ttybit;
 340:             bar &= ~ttybit;
 341:             tp = &dh11[unit];
 342:             tp->t_state &= ~BUSY;
 343:             if (tp->t_state & FLUSH)
 344:                 tp->t_state &= ~FLUSH;
 345:             else {
 346: #if !defined(UCB_CLIST) || defined (UNIBUS_MAP)
 347:                 /*
 348: 				 * Clists are either:
 349: 				 *	1)  in kernel virtual space,
 350: 				 *	    which in turn lies in the
 351: 				 *	    first 64K of physical memory or
 352: 				 *	2)  at UNIBUS virtual address 0.
 353: 				 *
 354: 				 * In either case, the extension bits are 0.
 355: 				 */
 356:                 addr->un.dhcsrl = (unit & 017) | DH_IE;
 357:                 ndflush(&q3,
 358:                     (short)(addr->dhcar - cpaddr(q3.c_cf)));
 359: #else   /* defined(UCB_CLIST) && !defined(UNIBUS_MAP) */
 360:                 ubadr_t car;
 361:                 int count;
 362: 
 363:                 addr->un.dhcsrl = (unit & 017) | DH_IE;
 364:                 car = (ubadr_t) addr->dhcar
 365:                     | (ubadr_t)(addr->dhsilo & 0300) << 10;
 366:                 count = car - cpaddr(q3.c_cf);
 367:                 ndflush(&q3, count);
 368: #endif
 369:             }
 370:             dhstart(tp);
 371:         }
 372:     }
 373: }
 374: 
 375: /*
 376:  * Start (restart) transmission on the given DH line.
 377:  */
 378: dhstart(tp)
 379: register struct tty *tp;
 380: {
 381:     register struct dhdevice *addr;
 382:     register nch;
 383:     int s, unit;
 384: 
 385:     unit = (int) (tp - dh11);
 386:     addr = (struct dhdevice *) tp->t_addr;
 387: 
 388:     /*
 389: 	 * Must hold interrupts in following code to prevent
 390: 	 * state of the tp from changing.
 391: 	 */
 392:     s = spl5();
 393: 
 394:     /*
 395: 	 * If it's currently active, or delaying, no need to do anything.
 396: 	 */
 397:     if (tp->t_state & (TIMEOUT | BUSY | TTSTOP))
 398:         goto out;
 399:     /*
 400: 	 * If there are sleepers, and the output has drained below low
 401: 	 * water mark, wake up the sleepers.
 402: 	 */
 403:     if (tp->t_outq.c_cc<=TTLOWAT(tp)) {
 404:         if (tp->t_state&ASLEEP) {
 405:             tp->t_state &= ~ASLEEP;
 406: #ifdef  MPX_FILS
 407:             if (tp->t_chan)
 408:                 mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
 409:             else
 410: #endif
 411:                 wakeup((caddr_t)&tp->t_outq);
 412:         }
 413: #ifdef  UCB_NET
 414:         if (tp->t_wsel) {
 415:             selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
 416:             tp->t_wsel = 0;
 417:             tp->t_state &= ~TS_WCOLL;
 418:         }
 419: #endif
 420:     }
 421: 
 422:     /*
 423: 	 * Now restart transmission unless the output queue is
 424: 	 * empty.
 425: 	 */
 426:     if (tp->t_outq.c_cc == 0)
 427:         goto out;
 428: #ifdef  UCB_NTTY
 429:     if ((tp->t_flags & RAW) || (tp->t_local & LLITOUT))
 430: #else
 431:     if (tp->t_flags & RAW)
 432: #endif
 433:         nch = ndqb(&tp->t_outq, 0);
 434:     else {
 435:         nch = ndqb(&tp->t_outq, 0200);
 436:         /*
 437: 		 * If first thing on queue is a delay, process it.
 438: 		 */
 439:         if (nch == 0) {
 440:             nch = getc(&tp->t_outq);
 441:             timeout(ttrstrt, (caddr_t) tp, (nch & 0177) + 6);
 442:             tp->t_state |= TIMEOUT;
 443:             goto out;
 444:         }
 445:     }
 446:     /*
 447: 	 * If characters to transmit, restart transmission.
 448: 	 */
 449:     if (nch) {
 450: #if !defined(UCB_CLIST) || defined (UNIBUS_MAP)
 451:         addr->un.dhcsrl = (unit & 017) | DH_IE;
 452:         addr->dhcar = (short)cpaddr(tp->t_outq.c_cf);
 453: #else   /* defined(UCB_CLIST) && !defined(UNIBUS_MAP) */
 454:         ubadr_t uba;
 455: 
 456:         uba = cpaddr(tp->t_outq.c_cf);
 457:         addr->un.dhcsrl = (unit&017) | DH_IE | ((hiint(uba) << 4) & 060);
 458:         addr->dhcar = loint(uba);
 459: #endif
 460:         addr->dhbcr = -nch;
 461:         nch = 1 << (unit & 017);
 462:         addr->dhbar |= nch;
 463:         dhsar[unit >> 4] |= nch;
 464:         tp->t_state |= BUSY;
 465:     }
 466:     out:
 467:     splx(s);
 468: }
 469: 
 470: 
 471: /*
 472:  * Stop output on a line, e.g. for ^S/^Q or output flush.
 473:  */
 474: /*ARGSUSED*/
 475: dhstop(tp, flag)
 476: register struct tty *tp;
 477: {
 478:     register struct dhdevice *addr;
 479:     register unit;
 480:     int s;
 481: 
 482:     addr = (struct dhdevice *)tp->t_addr;
 483:     /*
 484: 	 * Block input/output interrupts while messing with state.
 485: 	 */
 486:     s = spl6();
 487:     if (tp->t_state & BUSY) {
 488:         /*
 489: 		 * Device is transmitting; stop output
 490: 		 * by selecting the line and setting the byte
 491: 		 * count to -1.  We will clean up later
 492: 		 * by examining the address where the dh stopped.
 493: 		 */
 494:         unit = DHLINE(tp->t_dev);
 495:         addr->un.dhcsrl = (unit & 017) | DH_IE;
 496:         if ((tp->t_state & TTSTOP) == 0) {
 497:             tp->t_state |= FLUSH;
 498:         }
 499:         addr->dhbcr = -1;
 500:     }
 501:     splx(s);
 502: }
 503: 
 504: #ifdef  DH_SILO
 505: void
 506: dhtimer(dev)
 507: dev_t   dev;
 508: {
 509:     register dh, cc;
 510:     register struct dhdevice *addr;
 511: 
 512:     dh = 0;
 513:     do {
 514:         addr = dh_addr[dh];
 515:         cc = dhchars[dh];
 516:         dhchars[dh] = 0;
 517:         if (cc > 50)
 518:             cc = 32;
 519:         else
 520:             if (cc > 16)
 521:                 cc = 16;
 522:             else
 523:                 cc = 0;
 524:         addr->dhsilo = cc;
 525:         dhrint(dh++);
 526:     } while (dh < NDH);
 527:     timeout(dhtimer, (caddr_t) 0, SILOSCANRATE);
 528: }
 529: #endif	DH_SILO
 530: 
 531: #if NDM > 0
 532: 
 533: dmattach(addr, unit)
 534: struct device *addr;
 535: {
 536:     if ((unsigned) unit >= NDM)
 537:         return 0;
 538:     dm_addr[unit] = addr;
 539:     return 1;
 540: }
 541: 
 542: /*
 543:  * Turn on the line associated with the dh device dev.
 544:  */
 545: dmopen(dev)
 546: dev_t   dev;
 547: {
 548:     register struct tty *tp;
 549:     register struct dmdevice *addr;
 550:     register unit;
 551:     int s;
 552: 
 553:     unit = DHLINE(dev);
 554:     tp = &dh11[unit];
 555:     if ((unit < dhlowdm) || (unit >= dhlowdm + dhndm)
 556:        || ((addr = dm_addr[(unit - dhlowdm) >> 4]) == 0)
 557: #ifdef  DH_SOFTCAR
 558:        || (dev & 0200)
 559: #endif
 560:        ) {
 561:         tp->t_state |= CARR_ON;
 562:         return;
 563:     }
 564:     s = spl5();
 565:     addr->dmcsr &= ~DM_SE;
 566:     while (addr->dmcsr & DM_BUSY)
 567:         ;
 568:     addr->dmcsr = unit & 017;
 569:     addr->dmlstat = DML_ON;
 570:     if (addr->dmlstat & DML_CAR)
 571:         tp->t_state |= CARR_ON;
 572:     addr->dmcsr = DM_IE | DM_SE;
 573:     while ((tp->t_state & CARR_ON)==0)
 574:         sleep((caddr_t) &tp->t_rawq, TTIPRI);
 575:     addr->dmcsr = unit & 017;
 576:     if (addr->dmlstat & DML_SR) {
 577:         tp->t_ispeed = B1200;
 578:         tp->t_ospeed = B1200;
 579:         dhparam(unit);
 580:     }
 581:     addr->dmcsr = DM_IE | DM_SE;
 582:     splx(s);
 583: }
 584: 
 585: /*
 586:  * Dump control bits into the DM registers.
 587:  */
 588: dmctl(unit, bits, how)
 589: register unit;
 590: {
 591:     register struct dmdevice *addr;
 592:     register s;
 593: 
 594:     if(unit < dhlowdm || unit >= dhlowdm + dhndm)
 595:         return;
 596:     addr = dm_addr[(unit - dhlowdm) >> 4];
 597:     s = spl5();
 598:     addr->dmcsr &= ~DM_SE;
 599:     while (addr->dmcsr & DM_BUSY)
 600:         ;
 601:     addr->dmcsr = unit & 017;
 602:     switch (how) {
 603:         case DMSET:
 604:             addr->dmlstat = bits;
 605:             break;
 606:         case DMBIS:
 607:             addr->dmlstat |= bits;
 608:             break;
 609:         case DMBIC:
 610:             addr->dmlstat &= ~bits;
 611:             break;
 612:         }
 613:     addr->dmcsr = DM_IE | DM_SE;
 614:     splx(s);
 615: }
 616: 
 617: /*
 618:  * DM interrupt; deal with carrier transitions.
 619:  */
 620: dmintr(dm)
 621: register dm;
 622: {
 623:     register struct tty *tp;
 624:     register struct dmdevice *addr;
 625: 
 626:     addr = dm_addr[dm];
 627:     if (addr->dmcsr & DM_DONE) {
 628:         if (addr->dmcsr & DM_CF) {
 629:             tp = &dh11[(dm << 4) + (addr->dmcsr & 017)];
 630:             tp += dhlowdm;
 631:             if (tp < &dh11[dhlowdm + dhndm]) {
 632:                 wakeup((caddr_t)&tp->t_rawq);
 633: #ifdef  UCB_NTTY
 634:                 if ((tp->t_state & WOPEN) == 0
 635:                     && (tp->t_local & LMDMBUF)) {
 636:                     if ((addr->dmlstat & DML_CAR)) {
 637:                         tp->t_state &= ~TTSTOP;
 638:                         ttstart(tp);
 639:                     } else if ((tp->t_state&TTSTOP) == 0) {
 640:                         tp->t_state |= TTSTOP;
 641:                         dhstop(tp, 0);
 642:                     }
 643:                 } else
 644: #endif
 645:                 if ((addr->dmlstat & DML_CAR) == 0) {
 646:                     if ((tp->t_state & WOPEN)==0
 647: #ifdef  UCB_NTTY
 648:                     && (tp->t_local & LNOHANG)==0
 649: #endif
 650: #ifdef  DH_SOFTCAR
 651:                     && (tp->t_dev & 0200)==0
 652: #endif
 653:                     ) {
 654:                         gsignal(tp->t_pgrp, SIGHUP);
 655:                         addr->dmlstat = 0;
 656:                         flushtty(tp, FREAD|FWRITE);
 657:                     }
 658:                     tp->t_state &= ~CARR_ON;
 659:                 } else
 660:                     tp->t_state |= CARR_ON;
 661:             }
 662:         }
 663:         addr->dmcsr = DM_IE | DM_SE;
 664:     }
 665: }
 666: #endif	NDM
 667: #endif	NDH

Defined functions

dhattach defined in line 61; never used
dhclose defined in line 133; never used
dhioctl defined in line 231; never used
dhopen defined in line 75; never used
dhparam defined in line 271; used 4 times
dhread defined in line 153; never used
dhrint defined in line 176; used 5 times
dhstart defined in line 378; used 3 times
dhstop defined in line 475; used 1 times
dhtimer defined in line 505; used 3 times
dhwrite defined in line 165; never used
dhxint defined in line 319; used 4 times
dmattach defined in line 533; never used
dmctl defined in line 588; used 4 times
dmintr defined in line 620; used 4 times
dmopen defined in line 545; used 1 times

Defined variables

dh11 defined in line 39; used 13 times
dh_addr defined in line 51; used 5 times
dhchars defined in line 47; used 3 times
dhlowdm defined in line 41; used 8 times
dhndm defined in line 42; used 3 times
dhsar defined in line 59; used 2 times
dm_addr defined in line 53; used 4 times
ndh11 defined in line 40; never used

Defined macros

DHLINE defined in line 35; used 7 times
NDHLINE defined in line 38; used 4 times
SILOSCANRATE defined in line 46; used 2 times
cpaddr defined in line 29; used 4 times
q3 defined in line 17; used 4 times
Last modified: 1983-11-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1967
Valid CSS Valid XHTML 1.0 Strict