1: /*
   2:  * Copyright (c) 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:  *	@(#)dhu.c	2.3 (2.11BSD GTE) 1997/5/9
   7:  */
   8: 
   9: /*
  10:  * Rewritten for hardware flow control - sms 1997/5/9
  11:  *
  12:  * based on	dh.c 6.3	84/03/15
  13:  * and on	dmf.c	6.2	84/02/16
  14:  *
  15:  * Dave Johnson, Brown University Computer Science
  16:  *	ddj%brown@csnet-relay
  17:  */
  18: 
  19: #include "dhu.h"
  20: #if NDHU > 0
  21: /*
  22:  * DHU-11 driver
  23:  */
  24: #include "param.h"
  25: #include "dhureg.h"
  26: #include "conf.h"
  27: #include "user.h"
  28: #include "file.h"
  29: #include "ioctl.h"
  30: #include "tty.h"
  31: #include "clist.h"
  32: #include "map.h"
  33: #include "proc.h"
  34: #include "uba.h"
  35: #include "ubavar.h"
  36: #include "systm.h"
  37: #include "syslog.h"
  38: #include <sys/kernel.h>
  39: 
  40: struct  uba_device dhuinfo[NDHU];
  41: 
  42: #define NDHULINE    (NDHU*16)
  43: 
  44: #define UNIT(x) (minor(x) & 077)
  45: #define SOFTCAR 0x80
  46: #define HWFLOW  0x40
  47: 
  48: #define ISPEED  B9600
  49: #define IFLAGS  (EVENP|ODDP|ECHO)
  50: 
  51: /*
  52:  * default receive silo timeout value -- valid values are 2..255
  53:  * number of ms. to delay between first char received and receive interrupt
  54:  *
  55:  * A value of 20 gives same response as ABLE dh/dm with silo alarm = 0
  56:  */
  57: int dhu_def_timo = 20;
  58: 
  59: /*
  60:  * Baud rates: no 50, 200, or 38400 baud; all other rates are from "Group B".
  61:  *	EXTA => 19200 baud
  62:  *	EXTB => 2000 baud
  63:  */
  64: char    dhu_speeds[] =
  65:     { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 8, 10, 11, 13, 14, 9 };
  66: 
  67: struct  tty dhu_tty[NDHULINE];
  68: int ndhu = NDHULINE;
  69: int dhuact;             /* mask of active dhu's */
  70: int dhu_overrun[NDHULINE];
  71: int dhustart();
  72: long    dhumctl(),dmtodhu();
  73: extern  int wakeup();
  74: 
  75: #if defined(UCB_CLIST)
  76: extern  ubadr_t clstaddr;
  77: #define cpaddr(x)   (clstaddr + (ubadr_t)((x) - (char *)cfree))
  78: #else
  79: #define cpaddr(x)   ((u_short)(x))
  80: #endif
  81: 
  82: /*
  83:  * Routine called to attach a dhu.
  84:  * Called duattached for autoconfig.
  85:  */
  86: duattach(addr,unit)
  87:     register caddr_t addr;
  88:     register u_int unit;
  89:     {
  90:     register struct uba_device *ui;
  91: 
  92:     if  (addr && unit < NDHU && !dhuinfo[unit].ui_addr)
  93:         {
  94:         ui = &dhuinfo[unit];
  95:         ui->ui_unit = unit;
  96:         ui->ui_addr = addr;
  97:         ui->ui_alive = 1;
  98:         return(1);
  99:         }
 100:     return(0);
 101:     }
 102: 
 103: /*
 104:  * Open a DHU11 line, mapping the clist onto the uba if this
 105:  * is the first dhu on this uba.  Turn on this dhu if this is
 106:  * the first use of it.
 107: */
 108: /*ARGSUSED*/
 109: dhuopen(dev, flag)
 110:     dev_t dev;
 111:     int flag;
 112:     {
 113:     register struct tty *tp;
 114:     int unit, dhu;
 115:     register struct dhudevice *addr;
 116:     register struct uba_device *ui;
 117:     int s, error;
 118: 
 119:     unit = UNIT(dev);
 120:     dhu = unit >> 4;
 121:     if  (unit >= NDHULINE || (ui = &dhuinfo[dhu])->ui_alive == 0)
 122:         return (ENXIO);
 123:     tp = &dhu_tty[unit];
 124:     addr = (struct dhudevice *)ui->ui_addr;
 125:     tp->t_addr = (caddr_t)addr;
 126:     tp->t_oproc = dhustart;
 127: 
 128:     if  ((dhuact&(1<<dhu)) == 0)
 129:         {
 130:         addr->dhucsr = DHU_SELECT(0) | DHU_IE;
 131:         addr->dhutimo = dhu_def_timo;
 132:         dhuact |= (1<<dhu);
 133:         /* anything else to configure whole board */
 134:         }
 135:     /*
 136: 	 * If this is first open, initialize tty state to default.
 137: 	 */
 138:     s = spltty();
 139:     if  ((tp->t_state&TS_ISOPEN) == 0)
 140:         {
 141:         tp->t_state |= TS_WOPEN;
 142:         if  (tp->t_ispeed == 0)
 143:             {
 144:             tp->t_state |= TS_HUPCLS;
 145:             tp->t_ispeed = ISPEED;
 146:             tp->t_ospeed = ISPEED;
 147:             tp->t_flags = IFLAGS;
 148:             }
 149:         ttychars(tp);
 150:         tp->t_dev = dev;
 151:         if  (dev & HWFLOW)
 152:             tp->t_flags |= RTSCTS;
 153:         else
 154:             tp->t_flags &= ~RTSCTS;
 155:         dhuparam(unit);
 156:         }
 157:     else if (tp->t_state & TS_XCLUDE && u.u_uid)
 158:         {
 159:         error = EBUSY;
 160:         goto out;
 161:         }
 162: /*
 163:  * Turn the device on.  Wait for carrier (the wait is short if this is a
 164:  * softcarrier/hardwired line ;-)).  Then do the line discipline specific open.
 165: */
 166:     dhumctl(dev, (long)DHU_ON, DMSET);
 167:     addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
 168:     if  ((addr->dhustat & DHU_ST_DCD) || (dev & SOFTCAR))
 169:         tp->t_state |= TS_CARR_ON;
 170:     while   ((tp->t_state & TS_CARR_ON) == 0 &&
 171:          (flag & O_NONBLOCK) == 0)
 172:         {
 173:         tp->t_state |= TS_WOPEN;
 174:         sleep((caddr_t)&tp->t_rawq, TTIPRI);
 175:         }
 176:     error = (*linesw[tp->t_line].l_open)(dev, tp);
 177: out:
 178:     splx(s);
 179:     return(error);
 180:     }
 181: 
 182: /*
 183:  * Close a DHU11 line.  Clear the 'break' state in case it's asserted and
 184:  * then drop DTR+RTS.
 185:  */
 186: /*ARGSUSED*/
 187: dhuclose(dev, flag)
 188:     dev_t dev;
 189:     int flag;
 190:     {
 191:     register struct tty *tp;
 192:     register int unit;
 193: 
 194:     unit = UNIT(dev);
 195:     tp = &dhu_tty[unit];
 196: /*
 197:  * Do we need to do this?  Perhaps this should be ifdef'd.  I can't see how
 198:  * this can happen...
 199: */
 200:     if  (!(tp->t_state & TS_ISOPEN))
 201:         return(EBADF);
 202:     (*linesw[tp->t_line].l_close)(tp, flag);
 203:     (void) dhumctl(unit, (long)DHU_BRK, DMBIC);
 204:     (void) dhumctl(unit, DHU_OFF, DMSET);
 205:     ttyclose(tp);
 206:     if  (dhu_overrun[unit])
 207:         {
 208:         log(LOG_NOTICE, "dhu%d %d overruns\n", unit, dhu_overrun[unit]);
 209:         dhu_overrun[unit] = 0;
 210:         }
 211:     return(0);
 212:     }
 213: 
 214: dhuselect(dev, rw)
 215:     dev_t   dev;
 216:     int rw;
 217:     {
 218: 
 219:     return(ttyselect(&dhu_tty[UNIT(dev)], rw));
 220:     }
 221: 
 222: dhuread(dev, uio, flag)
 223:     dev_t dev;
 224:     struct uio *uio;
 225:     {
 226:     register struct tty *tp = &dhu_tty[UNIT(dev)];
 227: 
 228:     return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
 229:     }
 230: 
 231: dhuwrite(dev, uio, flag)
 232:     dev_t dev;
 233:     struct uio *uio;
 234:     {
 235:     register struct tty *tp = &dhu_tty[UNIT(dev)];
 236: 
 237:     return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
 238:     }
 239: 
 240: /*
 241:  * DHU11 receiver interrupt.
 242: */
 243: dhurint(dhu)
 244:     int dhu;
 245:     {
 246:     register struct tty *tp;
 247:     register int    c;
 248:     register struct dhudevice *addr;
 249:     struct tty *tp0;
 250:     struct uba_device *ui;
 251:     int line;
 252: 
 253:     ui = &dhuinfo[dhu];
 254:     addr = (struct dhudevice *)ui->ui_addr;
 255:     if  (!addr)
 256:         return;
 257:     tp0 = &dhu_tty[dhu<<4];
 258:     /*
 259: 	 * Loop fetching characters from the silo for this
 260: 	 * dhu until there are no more in the silo.
 261: 	*/
 262:     while   ((c = addr->dhurbuf) < 0)
 263:         {   /* (c & DHU_RB_VALID) == on */
 264:         line = DHU_RX_LINE(c);
 265:         tp = tp0 + line;
 266:         if  ((c & DHU_RB_STAT) == DHU_RB_STAT)
 267:             {
 268:             /*
 269: 			 * modem changed or diag info
 270: 			 */
 271:             if  (c & DHU_RB_DIAG)
 272:                 {
 273:                 if  ((c & 0xff) > 0201)
 274:                     log(LOG_NOTICE,"dhu%d diag %o\n",
 275:                         dhu, c);
 276:                 continue;
 277:                 }
 278:             if  (!(tp->t_dev & SOFTCAR) ||
 279:                   (tp->t_flags & MDMBUF))
 280:                 (*linesw[tp->t_line].l_modem)(tp,
 281:                         (c & DHU_ST_DCD) != 0);
 282:             if  (tp->t_flags & RTSCTS)
 283:                 {
 284:                 if  (c & DHU_ST_CTS)
 285:                     {
 286:                     tp->t_state &= ~TS_TTSTOP;
 287:                     ttstart(tp);
 288:                     }
 289:                 else
 290:                     {
 291:                     tp->t_state |= TS_TTSTOP;
 292:                     dhustop(tp, 0);
 293:                     }
 294:                 }
 295:             continue;
 296:             }
 297:         if  ((tp->t_state&TS_ISOPEN) == 0)
 298:             {
 299:             wakeup((caddr_t)&tp->t_rawq);
 300:             continue;
 301:             }
 302:         if  (c & DHU_RB_PE)
 303:             if  ((tp->t_flags&(EVENP|ODDP)) == EVENP ||
 304:                  (tp->t_flags&(EVENP|ODDP)) == ODDP)
 305:                 continue;
 306:         if  (c & DHU_RB_DO)
 307:             {
 308:             dhu_overrun[(dhu << 4) + line]++;
 309:             /* bit bucket the silo to free the cpu */
 310:             while   (addr->dhurbuf & DHU_RB_VALID)
 311:                 ;
 312:             break;
 313:             }
 314:         if  (c & DHU_RB_FE)
 315:             {
 316:             /*
 317: 			 * At framing error (break) generate
 318: 			 * a null (in raw mode, for getty), or a
 319: 			 * interrupt (in cooked/cbreak mode).
 320: 			 */
 321:             if (tp->t_flags&RAW)
 322:                 c = 0;
 323:             else
 324: #ifdef  OLDWAY
 325:                 c = tp->t_intrc;
 326: #else
 327:                 c = tp->t_brkc;
 328: #endif
 329:             }
 330: #if NBK > 0
 331:         if  (tp->t_line == NETLDISC)
 332:             {
 333:             c &= 0x7f;
 334:             BKINPUT(c, tp);
 335:             }
 336:         else
 337: #endif
 338:             (*linesw[tp->t_line].l_rint)(c, tp);
 339:         }
 340:     }
 341: 
 342: /*
 343:  * Ioctl for DHU11.
 344:  */
 345: /*ARGSUSED*/
 346: dhuioctl(dev, cmd, data, flag)
 347:     u_int cmd;
 348:     caddr_t data;
 349:     {
 350:     register struct tty *tp;
 351:     register int unit = UNIT(dev);
 352:     int error;
 353: 
 354:     tp = &dhu_tty[unit];
 355:     error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
 356:     if  (error >= 0)
 357:         return(error);
 358:     error = ttioctl(tp, cmd, data, flag);
 359:     if  (error >= 0)
 360:         {
 361:         if  (cmd == TIOCSETP || cmd == TIOCSETN ||
 362:              cmd == TIOCLSET || cmd == TIOCLBIC || cmd == TIOCLBIS)
 363:             dhuparam(unit);
 364:         return(error);
 365:         }
 366: 
 367:     switch  (cmd)
 368:         {
 369:         case    TIOCSBRK:
 370:             (void) dhumctl(unit, (long)DHU_BRK, DMBIS);
 371:             break;
 372:         case    TIOCCBRK:
 373:             (void) dhumctl(unit, (long)DHU_BRK, DMBIC);
 374:             break;
 375:         case    TIOCSDTR:
 376:             (void) dhumctl(unit, (long)DHU_DTR|DHU_RTS, DMBIS);
 377:             break;
 378:         case    TIOCCDTR:
 379:             (void) dhumctl(unit, (long)DHU_DTR|DHU_RTS, DMBIC);
 380:             break;
 381:         case    TIOCMSET:
 382:             (void) dhumctl(dev, dmtodhu(*(int *)data), DMSET);
 383:             break;
 384:         case    TIOCMBIS:
 385:             (void) dhumctl(dev, dmtodhu(*(int *)data), DMBIS);
 386:             break;
 387:         case    TIOCMBIC:
 388:             (void) dhumctl(dev, dmtodhu(*(int *)data), DMBIC);
 389:             break;
 390:         case    TIOCMGET:
 391:             *(int *)data = dhutodm(dhumctl(dev, 0L, DMGET));
 392:             break;
 393:         default:
 394:             return(ENOTTY);
 395:         }
 396:     return(0);
 397:     }
 398: 
 399: static long
 400: dmtodhu(bits)
 401:     register int bits;
 402:     {
 403:     long b = 0;
 404: 
 405:     if  (bits & TIOCM_RTS) b |= DHU_RTS;
 406:     if  (bits & TIOCM_DTR) b |= DHU_DTR;
 407:     if  (bits & TIOCM_LE) b |= DHU_LE;
 408:     return(b);
 409:     }
 410: 
 411: static
 412: dhutodm(bits)
 413:     long bits;
 414:     {
 415:     register int b = 0;
 416: 
 417:     if  (bits & DHU_DSR) b |= TIOCM_DSR;
 418:     if  (bits & DHU_RNG) b |= TIOCM_RNG;
 419:     if  (bits & DHU_CAR) b |= TIOCM_CAR;
 420:     if  (bits & DHU_CTS) b |= TIOCM_CTS;
 421:     if  (bits & DHU_RTS) b |= TIOCM_RTS;
 422:     if  (bits & DHU_DTR) b |= TIOCM_DTR;
 423:     if  (bits & DHU_LE) b |= TIOCM_LE;
 424:     return(b);
 425:     }
 426: 
 427: /*
 428:  * Set parameters from open or stty into the DHU hardware
 429:  * registers.
 430:  */
 431: static
 432: dhuparam(unit)
 433:     register int unit;
 434:     {
 435:     register struct tty *tp;
 436:     register struct dhudevice *addr;
 437:     register int lpar;
 438:     int s;
 439: 
 440:     tp = &dhu_tty[unit];
 441:     addr = (struct dhudevice *)tp->t_addr;
 442:     /*
 443: 	 * Block interrupts so parameters will be set
 444: 	 * before the line interrupts.
 445: 	 */
 446:     s = spltty();
 447:     if  (tp->t_ispeed == 0)
 448:         {
 449:         tp->t_state |= TS_HUPCLS;
 450:         (void)dhumctl(unit, (long)DHU_OFF, DMSET);
 451:         goto out;
 452:         }
 453:     lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8);
 454:     if  ((tp->t_ispeed) == B134)
 455:         lpar |= DHU_LP_BITS6|DHU_LP_PENABLE;
 456:     else if (tp->t_flags & (RAW|LITOUT|PASS8))
 457:         lpar |= DHU_LP_BITS8;
 458:     else
 459:         lpar |= DHU_LP_BITS7|DHU_LP_PENABLE;
 460:     if  (tp->t_flags&EVENP)
 461:         lpar |= DHU_LP_EPAR;
 462:     if  ((tp->t_ospeed) == B110)
 463:         lpar |= DHU_LP_TWOSB;
 464:     addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
 465:     addr->dhulpr = lpar;
 466: out:
 467:     splx(s);
 468:     return;
 469:     }
 470: 
 471: /*
 472:  * DHU11 transmitter interrupt.
 473:  * Restart each line which used to be active but has
 474:  * terminated transmission since the last interrupt.
 475:  */
 476: dhuxint(dhu)
 477:     int dhu;
 478:     {
 479:     register struct tty *tp;
 480:     register struct dhudevice *addr;
 481:     struct tty *tp0;
 482:     struct uba_device *ui;
 483:     register int line, t;
 484:     u_short cntr;
 485:     ubadr_t base;
 486: 
 487:     ui = &dhuinfo[dhu];
 488:     tp0 = &dhu_tty[dhu<<4];
 489:     addr = (struct dhudevice *)ui->ui_addr;
 490:     while   ((t = addr->dhucsrh) & DHU_CSH_TI)
 491:         {
 492:         line = DHU_TX_LINE(t);
 493:         tp = tp0 + line;
 494:         tp->t_state &= ~TS_BUSY;
 495:         if  (t & DHU_CSH_NXM)
 496:             {
 497:             log(LOG_NOTICE, "dhu%d,%d NXM\n", dhu, line);
 498:             /* SHOULD RESTART OR SOMETHING... */
 499:             }
 500:         if  (tp->t_state&TS_FLUSH)
 501:             tp->t_state &= ~TS_FLUSH;
 502:         else
 503:             {
 504:             addr->dhucsrl = DHU_SELECT(line) | DHU_IE;
 505:             base = (ubadr_t) addr->dhubar1;
 506:             /*
 507: 			 * Clists are either:
 508: 			 *	1)  in kernel virtual space,
 509: 			 *	    which in turn lies in the
 510: 			 *	    first 64K of physical memory or
 511: 			 *	2)  at UNIBUS virtual address 0.
 512: 			 *
 513: 			 * In either case, the extension bits are 0.
 514: 			*/
 515:             if  (!ubmap)
 516:                 base |= (ubadr_t)((addr->dhubar2 & 037) << 16);
 517:             cntr = base - cpaddr(tp->t_outq.c_cf);
 518:             ndflush(&tp->t_outq, cntr);
 519:             }
 520:         if  (tp->t_line)
 521:             (*linesw[tp->t_line].l_start)(tp);
 522:         else
 523:             dhustart(tp);
 524:         }
 525:     }
 526: 
 527: /*
 528:  * Start (restart) transmission on the given DHU11 line.
 529:  */
 530: dhustart(tp)
 531:     register struct tty *tp;
 532:     {
 533:     register struct dhudevice *addr;
 534:     register int unit, nch;
 535:     ubadr_t car;
 536:     int s;
 537: 
 538:     unit = UNIT(tp->t_dev);
 539:     addr = (struct dhudevice *)tp->t_addr;
 540: 
 541:     s = spltty();
 542:     /*
 543: 	 * If it's currently active, or delaying, no need to do anything.
 544: 	 */
 545:     if  (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
 546:         goto out;
 547:     /*
 548: 	 * If there are sleepers, and output has drained below low
 549: 	 * water mark, wake up the sleepers..
 550: 	 */
 551:     ttyowake(tp);
 552: 
 553:     /*
 554: 	 * Now restart transmission unless the output queue is
 555: 	 * empty.
 556: 	 */
 557:     if  (tp->t_outq.c_cc == 0)
 558:         goto out;
 559:     addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
 560: /*
 561:  * If CTS is off and we're doing hardware flow control then mark the output
 562:  * as stopped and do not transmit anything.
 563: */
 564:     if  ((addr->dhustat & DHU_ST_CTS) == 0 && (tp->t_flags & RTSCTS))
 565:         {
 566:         tp->t_state |= TS_TTSTOP;
 567:         goto out;
 568:         }
 569: /*
 570:  * This is where any per character delay handling for special characters
 571:  * would go if ever implemented again.  The call to ndqb would be replaced
 572:  * with a scan for special characters and then the appropriate sleep/wakeup
 573:  * done.
 574: */
 575:     nch = ndqb(&tp->t_outq, 0);
 576:     /*
 577: 	 * If characters to transmit, restart transmission.
 578: 	 */
 579:     if  (nch)
 580:         {
 581:         car = cpaddr(tp->t_outq.c_cf);
 582:         addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
 583:         addr->dhulcr &= ~DHU_LC_TXABORT;
 584:         addr->dhubcr = nch;
 585:         addr->dhubar1 = loint(car);
 586:         if  (ubmap)
 587:             addr->dhubar2 = (hiint(car) & DHU_BA2_XBA) | DHU_BA2_DMAGO;
 588:         else
 589:             addr->dhubar2 = (hiint(car) & 037) | DHU_BA2_DMAGO;
 590:         tp->t_state |= TS_BUSY;
 591:         }
 592: out:
 593:     splx(s);
 594:     }
 595: 
 596: /*
 597:  * Stop output on a line, e.g. for ^S/^Q or output flush.
 598:  */
 599: /*ARGSUSED*/
 600: dhustop(tp, flag)
 601:     register struct tty *tp;
 602:     {
 603:     register struct dhudevice *addr;
 604:     register int unit, s;
 605: 
 606:     addr = (struct dhudevice *)tp->t_addr;
 607:     /*
 608: 	 * Block input/output interrupts while messing with state.
 609: 	 */
 610:     s = spltty();
 611:     if  (tp->t_state & TS_BUSY)
 612:         {
 613:         /*
 614: 		 * Device is transmitting; stop output
 615: 		 * by selecting the line and setting the
 616: 		 * abort xmit bit.  We will get an xmit interrupt,
 617: 		 * where we will figure out where to continue the
 618: 		 * next time the transmitter is enabled.  If
 619: 		 * TS_FLUSH is set, the outq will be flushed.
 620: 		 * In either case, dhustart will clear the TXABORT bit.
 621: 		 */
 622:         unit = UNIT(tp->t_dev);
 623:         addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
 624:         addr->dhulcr |= DHU_LC_TXABORT;
 625:         if  ((tp->t_state&TS_TTSTOP)==0)
 626:             tp->t_state |= TS_FLUSH;
 627:         }
 628:     (void) splx(s);
 629:     }
 630: 
 631: /*
 632:  * DHU11 modem control
 633:  */
 634: static long
 635: dhumctl(dev, bits, how)
 636:     dev_t dev;
 637:     long bits;
 638:     int how;
 639:     {
 640:     register struct dhudevice *dhuaddr;
 641:     register int unit, line;
 642:     long mbits;
 643:     int s;
 644: 
 645:     unit = UNIT(dev);
 646:     dhuaddr = (struct dhudevice *)(dhu_tty[unit].t_addr);
 647:     line = unit & 0xf;
 648:     s = spltty();
 649:     dhuaddr->dhucsr = DHU_SELECT(line) | DHU_IE;
 650:     /*
 651: 	 * combine byte from stat register (read only, bits 16..23)
 652: 	 * with lcr register (read write, bits 0..15).
 653: 	 */
 654:     mbits = (u_short)dhuaddr->dhulcr | ((long)dhuaddr->dhustat << 16);
 655:     switch  (how)
 656:         {
 657:         case    DMSET:
 658:             mbits = (mbits & 0xff0000L) | bits;
 659:             break;
 660:         case    DMBIS:
 661:             mbits |= bits;
 662:             break;
 663:         case    DMBIC:
 664:             mbits &= ~bits;
 665:             break;
 666:         case    DMGET:
 667:             goto out;
 668:         }
 669:     dhuaddr->dhulcr = (mbits & 0xffffL) | DHU_LC_RXEN;
 670:     dhuaddr->dhulcr2 = DHU_LC2_TXEN;
 671: out:
 672:     (void) splx(s);
 673:     return(mbits);
 674: }
 675: #endif

Defined functions

dhuclose defined in line 187; never used
dhuioctl defined in line 346; never used
dhumctl defined in line 634; used 13 times
dhuopen defined in line 109; never used
dhuparam defined in line 431; used 2 times
dhuread defined in line 222; never used
dhurint defined in line 243; used 1 times
dhuselect defined in line 214; never used
dhustart defined in line 530; used 3 times
dhustop defined in line 600; used 1 times
dhutodm defined in line 411; used 1 times
dhuwrite defined in line 231; never used
dhuxint defined in line 476; used 1 times
dmtodhu defined in line 399; used 4 times
duattach defined in line 86; never used

Defined variables

dhu_def_timo defined in line 57; used 1 times
dhu_overrun defined in line 70; used 4 times
dhu_speeds defined in line 64; used 2 times
  • in line 453(2)
dhu_tty defined in line 67; used 10 times
dhuact defined in line 69; used 2 times
dhuinfo defined in line 40; used 5 times
ndhu defined in line 68; never used

Defined macros

HWFLOW defined in line 46; used 1 times
IFLAGS defined in line 49; used 1 times
ISPEED defined in line 48; used 2 times
NDHULINE defined in line 42; used 4 times
SOFTCAR defined in line 45; used 2 times
UNIT defined in line 44; used 9 times
cpaddr defined in line 79; used 2 times
Last modified: 1997-06-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4657
Valid CSS Valid XHTML 1.0 Strict