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

##### Functions

    dhvattach         X
    dhvclose          X
    dhvioctl          X
    dhvopen           X
    dhvread           X
    dhvrint           X
    dhvselect         X
    dhvstart          X
    dhvstop           X
    dhvwrite          X
    dhvxint           X

##### Variables

    dhv_hwxon         X
    dhv_overrun       X
    dhv_speeds        X
    dhv_tty           X
    dhvact            X
    dhvinfo           X
    ndhv              X

##### Macros

    HWFLOW            X
    IFLAGS            X
    NDHVLINE          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:  *	@(#)dhv.c	2.4 (2.11BSD 2.11BSD) 1997/5/31
       7:  */
       8:
       9: /*
      10:  * Rewritten to implement hardware flowcontrol. A lot of clean up was done
      11:  * and the formatting style change to aid in debugging.  1997/4/25 - sms
      12:  *
      13:  * ported to 2.11BSD (uio logic added) 12/22/91 - SMS
      14:  * based on	dh.c 6.3	84/03/15
      15:  * and on	dmf.c	6.2	84/02/16
      16:  *
      17:  * REAL(tm) dhv driver derived from dhu.c by
      18:  * Steve Nuchia at Baylor 22 November 1987
      19:  *	steve@eyeball.bcm.tmc.edu
      20:  *
      21:  * Dave Johnson, Brown University Computer Science
      22:  *	ddj%brown@csnet-relay
      23:  */
      24:
      25: #include "dhv.h"
      26: #if NDHV > 0
      27: /*
      28:  * DHV-11 driver
      29:  */
      30: #include "param.h"
      31: #include "dhvreg.h"
      32: #include "conf.h"
      33: #include "user.h"
      34: #include "file.h"
      35: #include "proc.h"
      36: #include "ioctl.h"
      37: #include "tty.h"
      38: #include "ttychars.h"
      39: #include "clist.h"
      40: #include "map.h"
      41: #include "uba.h"
      42: #include "ubavar.h"
      43: #include "systm.h"
      44: #include "syslog.h"
      45: #include <sys/kernel.h>
      46:
      47: struct  uba_device dhvinfo[NDHV];
      48:
      49: #define NDHVLINE    (NDHV*8)
      50:
      51: /*
      52:  * The minor device number is used as follows:
      53:  *
      54:  *  bits	meaning
      55:  *  0-2		unit number within board
      56:  *  3-5		board number (max of 8)
      57:  *  6		RTS/CTS flow control enabled
      58:  *  7		softcarrier (hardwired line)
      59: */
      60: #define UNIT(x) (minor(x) & 077)
      61: #define SOFTCAR 0x80
      62: #define HWFLOW  0x40
      63:
      64: #define IFLAGS  (EVENP|ODDP|ECHO)
      65:
      66: /*
      67:  * DHV's don't have a very good interrupt facility - you get an
      68:  * interrupt when the first character is put into the silo
      69:  * and nothing after that.  Previously an attempt was made to
      70:  * delay a couple of clock ticks with receive interrupts disabled.
      71:  *
      72:  * Unfortunately the code was ineffective because the number of ticks
      73:  * to delay was decremented if a full (90%) or overrun silo was encountered.
      74:  * After two such events the driver was back in interrupt per character
      75:  * mode thus wasting/negating the whole effort.
      76:  */
      77:
      78: char    dhv_hwxon[NDHVLINE];    /* hardware xon/xoff enabled, per line */
      79:
      80: /*
      81:  * Baud rates: no 50, 200, or 38400 baud; all other rates are from "Group B".
      82:  *	EXTA => 19200 baud
      83:  *	EXTB => 2000 baud
      84:  */
      85: char    dhv_speeds[] =
      86:     { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 8, 10, 11, 13, 14, 9 };
      87:
      88: struct  tty dhv_tty[NDHVLINE];
      89: int ndhv = NDHVLINE;
      90: int dhvact;             /* mask of active dhv's */
      91: int dhv_overrun[NDHVLINE];
      92: int dhvstart();
      93: long    dhvmctl(),dmtodhv();
      94: extern  int wakeup();
      95:
      96: #if defined(UCB_CLIST)
      97: extern  ubadr_t clstaddr;
      98: #define cpaddr(x)   (clstaddr + (ubadr_t)((x) - (char *)cfree))
      99: #else
     100: #define cpaddr(x)   ((u_short)(x))
     101: #endif
     102:
     103: /*
     104:  * Routine called to attach a dhv.
     105:  */
     106: dhvattach(addr,unit)
     107:     register caddr_t addr;
     108:     register u_int unit;
     109: {
     110:     if (addr && unit < NDHV && !dhvinfo[unit].ui_addr)
     111:     {
     112:     dhvinfo[unit].ui_unit = unit;
     113:     dhvinfo[unit].ui_addr = addr;
     114:     dhvinfo[unit].ui_alive = 1;
     115:     return (1);
     116:     }
     117:     return (0);
     118: }
     119:
     120: /*
     121:  * Open a DHV11 line, mapping the clist onto the uba if this
     122:  * is the first dhv on this uba.  Turn on this dhv if this is
     123:  * the first use of it.
     124:  */
     125: /*ARGSUSED*/
     126: dhvopen(dev, flag)
     127:     dev_t dev;
     128:     int     flag;
     129:     {
     130:     register struct tty *tp;
     131:     register int unit;
     132:     int dhv, error, s;
     133:     register struct dhvdevice *addr;
     134:     struct uba_device *ui;
     135:
     136:     unit = UNIT(dev);
     137:     dhv = unit >> 3;
     138:     if  (unit >= NDHVLINE || (ui = &dhvinfo[dhv])->ui_alive == 0)
     139:         return(ENXIO);
     140:     tp = &dhv_tty[unit];
     141:     addr = (struct dhvdevice *)ui->ui_addr;
     142:     tp->t_addr = (caddr_t)addr;
     143:     tp->t_oproc = dhvstart;
     144:
     145:     if  ((dhvact & (1<<dhv)) == 0)
     146:         {
     147:         addr->dhvcsr = DHV_SELECT(0) | DHV_IE;
     148:         dhvact |= (1<<dhv);
     149:         /* anything else to configure whole board */
     150:         }
     151:
     152:     s = spltty();
     153:     if  ((tp->t_state & TS_ISOPEN) == 0)
     154:         {
     155:         tp->t_state |= TS_WOPEN;
     156:         if  (tp->t_ispeed == 0)
     157:             {
     158:             tp->t_state |= TS_HUPCLS;
     159:             tp->t_ispeed = B9600;
     160:             tp->t_ospeed = B9600;
     161:             tp->t_flags = IFLAGS;
     162:             }
     163:         ttychars(tp);
     164:         tp->t_dev = dev;
     165:         if  (dev & HWFLOW)
     166:             tp->t_flags |= RTSCTS;
     167:         else
     168:             tp->t_flags &= ~RTSCTS;
     169:         dhvparam(unit);
     170:         }
     171:     else if ((tp->t_state & TS_XCLUDE) && u.u_uid)
     172:         {
     173:         error = EBUSY;
     174:         goto out;
     175:         }
     176:     dhvmctl(dev, (long)DHV_ON, DMSET);
     177:     addr->dhvcsr = DHV_SELECT(dev) | DHV_IE;
     178:     if  ((addr->dhvstat & DHV_ST_DCD) || (dev & SOFTCAR))
     179:         tp->t_state |= TS_CARR_ON;
     180:     while   ((tp->t_state & TS_CARR_ON) == 0 &&
     181:          (flag & O_NONBLOCK) == 0)
     182:         {
     183:         tp->t_state |= TS_WOPEN;
     184:         sleep((caddr_t)&tp->t_rawq, TTIPRI);
     185:         }
     186:     error = (*linesw[tp->t_line].l_open)(dev, tp);
     187: out:
     188:     splx(s);
     189:     return(error);
     190:     }
     191:
     192: /*
     193:  * Close a DHV11 line, turning off the modem control.
     194:  */
     195: /*ARGSUSED*/
     196: dhvclose(dev, flag)
     197:     dev_t dev;
     198:     int flag;
     199:     {
     200:     register struct tty *tp;
     201:     register int unit;
     202:
     203:     unit = UNIT(dev);
     204:     tp = &dhv_tty[unit];
     205:     if  (!(tp->t_state & (TS_WOPEN|TS_ISOPEN)))
     206:         return(0);
     207:     (*linesw[tp->t_line].l_close)(tp, flag);
     208:     (void) dhvmctl(unit, (long)DHV_BRK, DMBIC);
     209:     (void) dhvmctl(unit, (long)DHV_OFF, DMSET);
     210:     ttyclose(tp);
     211:     if  (dhv_overrun[unit])
     212:         {
     213:         log(LOG_NOTICE,"dhv%d %d overruns\n",unit,dhv_overrun[unit]);
     214:         dhv_overrun[unit] = 0;
     215:         }
     216:     return(0);
     217:     }
     218:
     219: dhvselect(dev, rw)
     220:     dev_t   dev;
     221:     int rw;
     222:     {
     223:     struct  tty *tp = &dhv_tty[UNIT(dev)];
     224:
     225:     return(ttyselect(tp, rw));
     226:     }
     227:
     228: dhvread(dev, uio, flag)
     229:     dev_t dev;
     230:     struct uio *uio;
     231:     int flag;
     232:     {
     233:     register struct tty *tp = &dhv_tty[UNIT(dev)];
     234:
     235:     return((*linesw[tp->t_line].l_read) (tp, uio, flag));
     236:     }
     237:
     238: dhvwrite(dev, uio, flag)
     239:     dev_t dev;
     240:     struct uio *uio;
     241:     int flag;
     242:     {
     243:     register struct tty *tp = &dhv_tty[UNIT(dev)];
     244:
     245:     return((*linesw[tp->t_line].l_write) (tp, uio, flag));
     246:     }
     247:
     248: /*
     249:  * DHV11 receiver interrupt.
     250:  */
     251:
     252: dhvrint(dhv)
     253:     int dhv;
     254:     {
     255:     register struct tty *tp;
     256:     register int    c;
     257:     register struct dhvdevice *addr;
     258:     struct tty *tp0;
     259:     struct uba_device *ui;
     260:     int line, p;
     261:
     262:     ui = &dhvinfo[dhv];
     263:     addr = (struct dhvdevice *)ui->ui_addr;
     264:     if  (!addr)
     265:         return;
     266:     tp0 = &dhv_tty[dhv<<3];
     267:
     268:     /*
     269: 	 * Loop fetching characters from the silo for this
     270: 	 * dhv until there are no more in the silo.
     271: 	 */
     272:     while   ((c = addr->dhvrbuf) & DHV_RB_VALID)
     273:         {
     274:         line = DHV_RX_LINE(c);
     275:         tp = tp0 + line;
     276:         if  ((c & DHV_RB_STAT) == DHV_RB_STAT)
     277:             {
     278:             /*
     279: 			 * modem changed or diag info
     280: 			 */
     281:             if  (c & DHV_RB_DIAG)
     282:                 {
     283:                 if  ((c & 0xff) > 0201)
     284:                     log(LOG_NOTICE,"dhv%d diag %o\n",dhv, c&0xff);
     285:                     continue;
     286:                 }
     287:             if  (!(tp->t_dev & SOFTCAR) ||
     288:                   (tp->t_flags & MDMBUF))
     289:                     (*linesw[tp->t_line].l_modem)(tp,
     290:                             (c & DHV_ST_DCD) != 0);
     291:             if  (tp->t_flags & RTSCTS)
     292:                 {
     293:                 if  (c & DHV_ST_CTS)
     294:                         {
     295:                     tp->t_state &= ~TS_TTSTOP;
     296:                     ttstart(tp);
     297:                         }
     298:                 else
     299:                     {
     300:                     tp->t_state |= TS_TTSTOP;
     301:                     dhvstop(tp, 0);
     302:                         }
     303:                 }
     304:             continue;
     305:             }
     306:         if  ((tp->t_state&TS_ISOPEN) == 0)
     307:             {
     308:                 wakeup((caddr_t)&tp->t_rawq);
     309:             continue;
     310:             }
     311:         if  (c & (DHV_RB_PE|DHV_RB_DO|DHV_RB_FE))
     312:             {
     313:                 if  (c & DHV_RB_PE)
     314:                 {
     315:                 p = tp->t_flags & (EVENP|ODDP);
     316:                 if  (p == EVENP || p == ODDP)
     317:                     continue;
     318:                 }
     319:             if  (c & DHV_RB_DO)
     320:                 {
     321:                 dhv_overrun[(dhv << 3) + line]++;
     322:                 /* bit-bucket the silo to free the cpu */
     323:                 while   (addr->dhvrbuf & DHV_RB_VALID)
     324:                     ;
     325:                 break;
     326:                 }
     327:             if  (c & DHV_RB_FE)
     328:                 {
     329: /*
     330:  * At framing error (break) generate an interrupt in cooked/cbreak mode.
     331:  * Let the char through in RAW mode for autobauding getty's.  The
     332:  * DH driver * has been using the 'brkc' character for years - see
     333:  * the comment in dh.c
     334: */
     335:                 if  (!(tp->t_flags&RAW))
     336: #ifdef  OLDWAY
     337:                     c = tp->t_intrc;
     338: #else
     339:                     c = tp->t_brkc;
     340:                 }
     341: #endif
     342:             }
     343: #if NBK > 0
     344:         if  (tp->t_line == NETLDISC)
     345:             {
     346:             c &= 0x7f;
     347:             BKINPUT(c, tp);
     348:             }
     349:         else
     350: #endif
     351:             {
     352:             if  (!(c & DHV_RB_PE) && dhv_hwxon[(dhv<<3)+line] &&
     353:                  ((c & 0x7f) == CSTOP || (c & 0x7f) == CSTART))
     354:                 continue;
     355:             (*linesw[tp->t_line].l_rint)(c, tp);
     356:             }
     357:         }
     358:     }
     359:
     360: /*
     361:  * Ioctl for DHV11.
     362:  */
     363: /*ARGSUSED*/
     364: dhvioctl(dev, cmd, data, flag)
     365:     register dev_t dev;
     366:     u_int cmd;
     367:     caddr_t data;
     368:     {
     369:     register struct tty *tp;
     370:     register int unit = UNIT(dev);
     371:     int error;
     372:
     373:     tp = &dhv_tty[unit];
     374:     error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
     375:     if  (error >= 0)
     376:         return(error);
     377:     error = ttioctl(tp, cmd, data, flag);
     378:     if  (error >= 0)
     379:         {
     380:         if  (cmd == TIOCSETP || cmd == TIOCSETN ||
     381:              cmd == TIOCLSET || cmd == TIOCLBIC ||
     382:              cmd == TIOCLBIS || cmd == TIOCSETD || cmd == TIOCSETC)
     383:             dhvparam(unit);
     384:         return(error);
     385:         }
     386:
     387:     switch  (cmd)
     388:         {
     389:         case    TIOCSBRK:
     390:             (void) dhvmctl(unit, (long)DHV_BRK, DMBIS);
     391:             break;
     392:         case    TIOCCBRK:
     393:             (void) dhvmctl(unit, (long)DHV_BRK, DMBIC);
     394:             break;
     395:         case    TIOCSDTR:
     396:             (void) dhvmctl(unit, (long)DHV_DTR|DHV_RTS, DMBIS);
     397:             break;
     398:         case    TIOCCDTR:
     399:             (void) dhvmctl(unit, (long)DHV_DTR|DHV_RTS, DMBIC);
     400:             break;
     401:         case    TIOCMSET:
     402:             (void) dhvmctl(dev, dmtodhv(*(int *)data), DMSET);
     403:             break;
     404:         case    TIOCMBIS:
     405:             (void) dhvmctl(dev, dmtodhv(*(int *)data), DMBIS);
     406:             break;
     407:         case    TIOCMBIC:
     408:             (void) dhvmctl(dev, dmtodhv(*(int *)data), DMBIC);
     409:             break;
     410:         case    TIOCMGET:
     411:             *(int *)data = dhvtodm(dhvmctl(dev, 0L, DMGET));
     412:             break;
     413:         default:
     414:             return(ENOTTY);
     415:         }
     416:     return(0);
     417:     }
     418:
     419: static long
     420: dmtodhv(bits)
     421:     register int bits;
     422:     {
     423:     long b = 0;
     424:
     425:     if  (bits & TIOCM_RTS) b |= DHV_RTS;
     426:     if  (bits & TIOCM_DTR) b |= DHV_DTR;
     427:     if  (bits & TIOCM_LE) b |= DHV_LE;
     428:     return(b);
     429:     }
     430:
     431: static
     432: dhvtodm(bits)
     433:     long bits;
     434:     {
     435:     register int b = 0;
     436:
     437:     if  (bits & DHV_DSR) b |= TIOCM_DSR;
     438:     if  (bits & DHV_RNG) b |= TIOCM_RNG;
     439:     if  (bits & DHV_CAR) b |= TIOCM_CAR;
     440:     if  (bits & DHV_CTS) b |= TIOCM_CTS;
     441:     if  (bits & DHV_RTS) b |= TIOCM_RTS;
     442:     if  (bits & DHV_DTR) b |= TIOCM_DTR;
     443:     if  (bits & DHV_LE) b |= TIOCM_LE;
     444:     return(b);
     445:     }
     446:
     447: /*
     448:  * Set parameters from open or stty into the DHV hardware
     449:  * registers.
     450:  */
     451: static
     452: dhvparam(unit)
     453:     int unit;
     454:     {
     455:     register struct tty *tp;
     456:     register struct dhvdevice *addr;
     457:     register int lpar;
     458:     int s;
     459:
     460:     tp = &dhv_tty[unit];
     461:     addr = (struct dhvdevice *)tp->t_addr;
     462:     /*
     463: 	 * Block interrupts so parameters will be set
     464: 	 * before the line interrupts.
     465: 	 */
     466:     s = spltty();
     467:     if  ((tp->t_ispeed) == 0)
     468:         {
     469:         tp->t_state |= TS_HUPCLS;
     470:         (void)dhvmctl(unit, (long)DHV_OFF, DMSET);
     471:         goto out;
     472:         }
     473:     lpar = (dhv_speeds[tp->t_ospeed]<<12) | (dhv_speeds[tp->t_ispeed]<<8);
     474:     if  (tp->t_ispeed == B134)
     475:         lpar |= DHV_LP_BITS6|DHV_LP_PENABLE;
     476:     else if (tp->t_flags & (RAW|LITOUT|PASS8))
     477:         lpar |= DHV_LP_BITS8;
     478:     else
     479:         lpar |= DHV_LP_BITS7|DHV_LP_PENABLE;
     480:     if  (tp->t_flags&EVENP)
     481:         lpar |= DHV_LP_EPAR;
     482:     if  ((tp->t_flags & EVENP) && (tp->t_flags & ODDP))
     483:         {
     484:         /* hack alert.  assume "allow both" means don't care */
     485:         /* trying to make xon/xoff work with evenp+oddp */
     486:         lpar |= DHV_LP_BITS8;
     487:         lpar &= ~DHV_LP_PENABLE;
     488:         }
     489:     if  ((tp->t_ospeed) == B110)
     490:         lpar |= DHV_LP_TWOSB;
     491:     addr->dhvcsr = DHV_SELECT(unit) | DHV_IE;
     492:     addr->dhvlpr = lpar;
     493:     dhv_hwxon[unit] = !(tp->t_flags & RAW) &&
     494:         (tp->t_line == OTTYDISC || tp->t_line == NTTYDISC) &&
     495:         tp->t_stopc == CSTOP && tp->t_startc == CSTART;
     496:
     497:     if  (dhv_hwxon[unit])
     498:         addr->dhvlcr |= DHV_LC_OAUTOF;
     499:     else
     500:         {
     501:         addr->dhvlcr &= ~DHV_LC_OAUTOF;
     502:         delay(25L); /* see the dhv manual, sec 3.3.6 */
     503:         addr->dhvlcr2 |= DHV_LC2_TXEN;
     504:         }
     505: out:
     506:     splx(s);
     507:     return;
     508:     }
     509:
     510: /*
     511:  * DHV11 transmitter interrupt.
     512:  * Restart each line which used to be active but has
     513:  * terminated transmission since the last interrupt.
     514:  */
     515: dhvxint(dhv)
     516:     int dhv;
     517:     {
     518:     register struct tty *tp;
     519:     register struct dhvdevice *addr;
     520:     struct tty *tp0;
     521:     struct uba_device *ui;
     522:     register int line, t;
     523:     u_short cntr;
     524:     ubadr_t base;
     525:
     526:     ui = &dhvinfo[dhv];
     527:     tp0 = &dhv_tty[dhv<<4];
     528:     addr = (struct dhvdevice *)ui->ui_addr;
     529:     while   ((t = addr->dhvcsrh) & DHV_CSH_TI)
     530:         {
     531:         line = DHV_TX_LINE(t);
     532:         tp = tp0 + line;
     533:         tp->t_state &= ~TS_BUSY;
     534:         if  (t & DHV_CSH_NXM)
     535:             {
     536:             log(LOG_NOTICE, "dhv%d,%d NXM\n", dhv, line);
     537:             /* SHOULD RESTART OR SOMETHING... */
     538:             }
     539:         if  (tp->t_state&TS_FLUSH)
     540:             tp->t_state &= ~TS_FLUSH;
     541:         else
     542:             {
     543:             addr->dhvcsrl = DHV_SELECT(line) | DHV_IE;
     544:             base = (ubadr_t) addr->dhvbar1;
     545:             /*
     546: 			 * Clists are either:
     547: 			 *	1)  in kernel virtual space,
     548: 			 *	    which in turn lies in the
     549: 			 *	    first 64K of physical memory or
     550: 			 *	2)  at UNIBUS virtual address 0.
     551: 			 *
     552: 			 * In either case, the extension bits are 0.
     553: 			 */
     554:             if  (!ubmap)
     555:                 base |= (ubadr_t)((addr->dhvbar2 & 037) << 16);
     556:                 cntr = base - cpaddr(tp->t_outq.c_cf);
     557:             ndflush(&tp->t_outq,cntr);
     558:             }
     559:         if  (tp->t_line)
     560:             (*linesw[tp->t_line].l_start)(tp);
     561:         else
     562:             dhvstart(tp);
     563:         }
     564:     }
     565:
     566: /*
     567:  * Start (restart) transmission on the given DHV11 line.
     568:  */
     569: dhvstart(tp)
     570:     register struct tty *tp;
     571:     {
     572:     register struct dhvdevice *addr;
     573:     register int unit, nch;
     574:     ubadr_t car;
     575:     int s;
     576:
     577:     unit = UNIT(tp->t_dev);
     578:     addr = (struct dhvdevice *)tp->t_addr;
     579:
     580:     /*
     581: 	 * Must hold interrupts in following code to prevent
     582: 	 * state of the tp from changing.
     583: 	 */
     584:     s = spltty();
     585:     /*
     586: 	 * If it's currently active, or delaying, no need to do anything.
     587: 	 */
     588:     if  (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
     589:         goto out;
     590:     /*
     591: 	 * If there are sleepers, and output has drained below low
     592: 	 * water mark, wake up the sleepers..
     593: 	 */
     594:     ttyowake(tp);
     595:
     596:     /*
     597: 	 * Now restart transmission unless the output queue is
     598: 	 * empty.
     599: 	 */
     600:     if  (tp->t_outq.c_cc == 0)
     601:         goto out;
     602:     addr->dhvcsrl = DHV_SELECT(unit) | DHV_IE;
     603: /*
     604:  * If CTS is off and we're doing hardware flow control then mark the output
     605:  * as stopped and do not transmit anything.
     606: */
     607:     if  ((addr->dhvstat & DHV_ST_CTS) == 0 && (tp->t_flags & RTSCTS))
     608:         {
     609:         tp->t_state |= TS_TTSTOP;
     610:         goto out;
     611:         }
     612: /*
     613:  * This is where any per character delay handling for special characters
     614:  * would go if ever implemented again.  The call to ndqb would be replaced
     615:  * with a scan for special characters and then the appropriate sleep/wakeup
     616:  * done.
     617: */
     618:     nch = ndqb(&tp->t_outq, 0);
     619:     /*
     620: 	 * If characters to transmit, restart transmission.
     621: 	 */
     622:     if  (nch)
     623:         {
     624:         car = cpaddr(tp->t_outq.c_cf);
     625:         addr->dhvcsrl = DHV_SELECT(unit) | DHV_IE;
     626:         addr->dhvlcr &= ~DHV_LC_TXABORT;
     627:         addr->dhvbcr = nch;
     628:         addr->dhvbar1 = loint(car);
     629:         if  (ubmap)
     630:             addr->dhvbar2 = (hiint(car) & DHV_BA2_XBA) | DHV_BA2_DMAGO;
     631:         else
     632:             addr->dhvbar2 = (hiint(car) & 037) | DHV_BA2_DMAGO;
     633:         tp->t_state |= TS_BUSY;
     634:         }
     635: out:
     636:     splx(s);
     637:     }
     638:
     639: /*
     640:  * Stop output on a line, e.g. for ^S/^Q or output flush.
     641:  */
     642: /*ARGSUSED*/
     643: dhvstop(tp, flag)
     644:     register struct tty *tp;
     645:     {
     646:     register struct dhvdevice *addr;
     647:     register int unit, s;
     648:
     649:     addr = (struct dhvdevice *)tp->t_addr;
     650:     /*
     651: 	 * Block input/output interrupts while messing with state.
     652: 	 */
     653:     s = spltty();
     654:     if  (tp->t_state & TS_BUSY)
     655:         {
     656:         /*
     657: 		 * Device is transmitting; stop output
     658: 		 * by selecting the line and setting the
     659: 		 * abort xmit bit.  We will get an xmit interrupt,
     660: 		 * where we will figure out where to continue the
     661: 		 * next time the transmitter is enabled.  If
     662: 		 * TS_FLUSH is set, the outq will be flushed.
     663: 		 * In either case, dhvstart will clear the TXABORT bit.
     664: 		 */
     665:         unit = UNIT(tp->t_dev);
     666:         addr->dhvcsrl = DHV_SELECT(unit) | DHV_IE;
     667:         addr->dhvlcr |= DHV_LC_TXABORT;
     668:         delay(25L); /* see the dhv manual, sec 3.3.6 */
     669:         addr->dhvlcr2 |= DHV_LC2_TXEN;
     670:         if  ((tp->t_state&TS_TTSTOP)==0)
     671:             tp->t_state |= TS_FLUSH;
     672:         }
     673:     (void) splx(s);
     674:     }
     675:
     676: /*
     677:  * DHV11 modem control
     678:  */
     679: static long
     680: dhvmctl(dev, bits, how)
     681:     dev_t dev;
     682:     long bits;
     683:     int how;
     684:     {
     685:     register struct dhvdevice *dhvaddr;
     686:     register int unit;
     687:     register struct tty *tp;
     688:     long mbits;
     689:     int s;
     690:
     691:     unit = UNIT(dev);
     692:     tp = dhv_tty + unit;
     693:     dhvaddr = (struct dhvdevice *) tp->t_addr;
     694:     s = spltty();
     695:     dhvaddr->dhvcsr = DHV_SELECT(unit) | DHV_IE;
     696:     /*
     697: 	 * combine byte from stat register (read only, bits 16..23)
     698: 	 * with lcr register (read write, bits 0..15).
     699: 	 */
     700:     mbits = (u_short)dhvaddr->dhvlcr | ((long)dhvaddr->dhvstat << 16);
     701:     switch  (how)
     702:         {
     703:         case    DMSET:
     704:             mbits = (mbits & 0xff0000L) | bits;
     705:             break;
     706:         case    DMBIS:
     707:             mbits |= bits;
     708:             break;
     709:         case    DMBIC:
     710:             mbits &= ~bits;
     711:             break;
     712:         case    DMGET:
     713:             (void) splx(s);
     714:             return(mbits);
     715:         }
     716:     dhvaddr->dhvlcr = (mbits & 0xffff) | DHV_LC_RXEN;
     717:     if  (dhv_hwxon[unit])
     718:         dhvaddr->dhvlcr |= DHV_LC_OAUTOF;
     719:     dhvaddr->dhvlcr2 = DHV_LC2_TXEN;
     720:     (void) splx(s);
     721:     return(mbits);
     722:     }
     723: #endif

#### Defined functions

dhvattach defined in line 106; never used
dhvclose defined in line 196; never used
dhvioctl defined in line 364; never used
dhvmctl defined in line 679; used 13 times

- in line 93, 176, 208-209(2), 390-411(8), 470

dhvopen defined in line 126; never used
dhvparam defined in line 451; used 2 times

- in line 169, 383

dhvread defined in line 228; never used
dhvrint defined in line 252; used 1 times

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

dhvselect defined in line 219; never used
dhvstart defined in line 569; used 3 times

- in line 92, 143, 562

dhvstop defined in line 643; used 1 times

- in line 301

dhvtodm defined in line 431; used 1 times

- in line 411

dhvwrite defined in line 238; never used
dhvxint defined in line 515; used 1 times

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

dmtodhv defined in line 419; used 4 times

- in line 93, 402-408(3)

#### Defined variables

dhv_hwxon defined in line 78; used 4 times

- in line 352, 493-497(2), 717

dhv_overrun defined in line 91; used 4 times

- in line 211-214(3), 321

dhv_speeds defined in line 85; used 2 times

- in line 473(2)

dhv_tty defined in line 88; used 10 times

- in line 140, 204, 223, 233, 243, 266, 373, 460, 527, 692

dhvact defined in line 90; used 2 times

- in line 145-148(2)

dhvinfo defined in line 47; used 7 times

- in line 110-114(4), 138, 262, 526

ndhv defined in line 89; never used

#### Defined macros

HWFLOW defined in line 62; used 1 times

- in line 165

IFLAGS defined in line 64; used 1 times

- in line 161

NDHVLINE defined in line 49; used 5 times

- in line 78, 88-91(3), 138

SOFTCAR defined in line 61; used 2 times

- in line 178, 287

UNIT defined in line 60; used 9 times

- in line 136, 203, 223, 233, 243, 370, 577, 665, 691

cpaddr defined in line 100; used 2 times

- in line 556, 624

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