# 2.11BSD#431 - /usr/src/sys/pdpuba/dhu.c

##### Functions

    dhuclose          X
    dhuioctl          X
    dhuopen           X
    dhuread           X
    dhurint           X
    dhuselect         X
    dhustart          X
    dhustop           X
    dhuwrite          X
    dhuxint           X
    duattach          X

##### Variables

    dhu_def_timo      X
    dhu_overrun       X
    dhu_speeds        X
    dhu_tty           X
    dhuact            X
    dhuinfo           X
    ndhu              X

##### Macros

    HWFLOW            X
    IFLAGS            X
    ISPEED            X
    NDHULINE          X
    SOFTCAR           X
    UNIT              X
    cpaddr            X

       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

- in line 72, 166, 203-204(2), 370-391(8), 450

dhuopen defined in line 109; never used
dhuparam defined in line 431; used 2 times

- in line 155, 363

dhuread defined in line 222; never used
dhurint defined in line 243; used 1 times

- in /usr/src/sys/pdp/scb.s line 393

dhuselect defined in line 214; never used
dhustart defined in line 530; used 3 times

- in line 71, 126, 523

dhustop defined in line 600; used 1 times

- in line 292

dhutodm defined in line 411; used 1 times

- in line 391

dhuwrite defined in line 231; never used
dhuxint defined in line 476; used 1 times

- in /usr/src/sys/pdp/scb.s line 394

dmtodhu defined in line 399; used 4 times

- in line 72, 382-388(3)

duattach defined in line 86; never used

#### Defined variables

dhu_def_timo defined in line 57; used 1 times

- in line 131

dhu_overrun defined in line 70; used 4 times

- in line 206-209(3), 308

dhu_speeds defined in line 64; used 2 times

- in line 453(2)

dhu_tty defined in line 67; used 10 times

- in line 123, 195, 219, 226, 235, 257, 354, 440, 488, 646

dhuact defined in line 69; used 2 times

- in line 128-132(2)

dhuinfo defined in line 40; used 5 times

- in line 92-94(2), 121, 253, 487

ndhu defined in line 68; never used

#### Defined macros

HWFLOW defined in line 46; used 1 times

- in line 151

IFLAGS defined in line 49; used 1 times

- in line 147

ISPEED defined in line 48; used 2 times

- in line 145-146(2)

NDHULINE defined in line 42; used 4 times

- in line 67-70(3), 121

SOFTCAR defined in line 45; used 2 times

- in line 168, 278

UNIT defined in line 44; used 9 times

- in line 119, 194, 219, 226, 235, 351, 538, 622, 645

cpaddr defined in line 79; used 2 times

- in line 517, 581

Last modified: 1997-06-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1650 |