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

##### Functions

    dhattach          X
    dhclose           X
    dhioctl           X
    dhopen            X
    dhparam           X
    dhread            X
    dhrint            X
    dhselect          X
    dhstart           X
    dhstop            X
    dhtimer           X
    dhwrite           X
    dhxint            X
    dmattach          X
    dmctl             X
    dmintr            X
    dmopen            X

##### Variables

    dh11              X
    dh_overrun        X
    dhact             X
    dhchars           X
    dhfasttimers      X
    dhhighrate        X
    dhinfo            X
    dhlowrate         X
    dhrate            X
    dhsar             X
    dhsilos           X
    dhslowtimers      X
    dhtransitions     X
    dminfo            X
    ndh11             X

##### Macros

    FASTTIMER         X
    HWFLOW            X
    IFLAGS            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:  *	@(#)dh.c	1.5 (2.11BSD GTE) 1997/6/12
       7:  */
       8:
       9: /*
      10:  * DH11, DM11 device drivers
      11:  */
      12:
      13: #include "dh.h"
      14: #if NDH > 0
      15: /*
      16:  * DH-11/DM-11 driver
      17:  */
      18: #include "param.h"
      19: #include "conf.h"
      20: #include "user.h"
      21: #include "file.h"
      22: #include "ioctl.h"
      23: #include "tty.h"
      24: #include "dhreg.h"
      25: #include "dmreg.h"
      26: #include "map.h"
      27: #include "uba.h"
      28: #include "ubavar.h"
      29: #include "clist.h"
      30: #include "systm.h"
      31: #include "vm.h"
      32: #include "kernel.h"
      33: #include "syslog.h"
      34: #include "proc.h"
      35:
      36: int dhtimer();
      37: struct  uba_device dhinfo[NDH];
      38: struct  uba_device dminfo[NDH];
      39:
      40: #define IFLAGS  (EVENP|ODDP|ECHO)
      41:
      42: /*
      43:  * Use 2 ticks rather than doing a divide of 'hz' by 30.  The old method
      44:  * would produce a scan rate of 1 tick if the lineclock was 50hz but 2 ticks
      45:  * if the lineclock was 60hz.
      46: */
      47: #define FASTTIMER   2   /* scan rate with silos on */
      48:
      49: /*
      50:  * Local variables for the driver
      51:  */
      52: short   dhsar[NDH];         /* software copy of last bar */
      53:
      54: struct  tty dh11[NDH*16];
      55: u_int   dh_overrun[NDH*16];     /* count of silo overruns, cleared on
      56: 					 * close.
      57: 					 */
      58: int ndh11   = NDH*16;
      59: int dhact;              /* mask of active dh's */
      60: int dhsilos;            /* mask of dh's with silo in use */
      61: int dhchars[NDH];           /* recent input count */
      62: int dhrate[NDH];            /* smoothed input count */
      63: int dhhighrate = 100;       /* silo on if dhchars > dhhighrate */
      64: int dhlowrate = 75;         /* silo off if dhrate < dhlowrate */
      65: static short timerstarted;
      66: int dhstart();
      67: static  int dmtodh(), dhtodm();
      68:
      69: #if defined(UCB_CLIST)
      70: extern  ubadr_t clstaddr;
      71: #define cpaddr(x)   (clstaddr + (ubadr_t)((x) - (char *)cfree))
      72: #else
      73: #define cpaddr(x)   (x)
      74: #endif
      75:
      76: #define UNIT(x) (x & 0x3f)
      77: #define SOFTCAR 0x80
      78: #define HWFLOW  0x40
      79:
      80: /*
      81:  * Routine called to attach a dh.
      82:  */
      83: dhattach(addr, unit)
      84:     register caddr_t addr;
      85:     register u_int unit;
      86: {
      87:     register struct uba_device *ui;
      88:
      89:     if (addr && unit < NDH && !dhinfo[unit].ui_addr) {
      90:         ui = &dhinfo[unit];
      91:         ui->ui_unit = unit;
      92:         ui->ui_addr = addr;
      93:         ui->ui_alive = 1;
      94:         return (1);
      95:     }
      96:     return (0);
      97: }
      98:
      99: /*ARGSUSED*/
     100: dmattach(addr, unit)
     101:     register caddr_t addr;
     102:     register u_int unit;
     103: {
     104:     register struct uba_device *ui;
     105:
     106:     if (addr && unit < NDH && !dminfo[unit].ui_addr) {
     107:         ui = &dminfo[unit];
     108:         ui->ui_unit = unit;
     109:         ui->ui_addr = addr;
     110:         ui->ui_alive = 1;
     111:         return (1);
     112:     }
     113:     return (0);
     114: }
     115:
     116: /*
     117:  * Open a DH11 line.  Turn on this dh if this is
     118:  * the first use of it.
     119:  */
     120: /*ARGSUSED*/
     121: dhopen(dev, flag)
     122:     dev_t dev;
     123:     {
     124:     register struct tty *tp;
     125:     register struct dhdevice *addr;
     126:     register int unit;
     127:     struct  uba_device *ui;
     128:     int dh, s, error;
     129:
     130:     unit = UNIT(dev);
     131:     dh = unit >> 4;
     132:     if  (unit >= NDH*16 || (ui = &dhinfo[dh])->ui_alive == 0)
     133:         return(ENXIO);
     134:     tp = &dh11[unit];
     135:     addr = (struct dhdevice *)ui->ui_addr;
     136:     tp->t_addr = (caddr_t)addr;
     137:     tp->t_oproc = dhstart;
     138:
     139:     if  (timerstarted == 0)
     140:         {
     141:         timerstarted++;
     142:         timeout(dhtimer, (caddr_t) 0, hz);
     143:         }
     144:     if  ((dhact&(1<<dh)) == 0)
     145:         {
     146:         addr->un.dhcsr |= DH_IE;
     147:         dhact |= (1<<dh);
     148:         addr->dhsilo = 0;
     149:         }
     150:     s = spltty();
     151:     if  ((tp->t_state & TS_ISOPEN) == 0)
     152:         {
     153:         tp->t_state |= TS_WOPEN;
     154:         if  (tp->t_ispeed == 0)
     155:             {
     156:             tp->t_state |= TS_HUPCLS;
     157:             tp->t_ispeed = B9600;
     158:             tp->t_ospeed = B9600;
     159:             tp->t_flags = IFLAGS;
     160:             }
     161:         ttychars(tp);
     162:         tp->t_dev = dev;
     163:         if  (dev & HWFLOW)
     164:             tp->t_flags |= RTSCTS;
     165:         else
     166:             tp->t_flags &= ~RTSCTS;
     167:         dhparam(unit);
     168:         }
     169:     else if ((tp->t_state & TS_XCLUDE) && u.u_uid)
     170:         {
     171:         error = EBUSY;
     172:         goto out;
     173:         }
     174:     dmopen(dev);
     175:     if  ((dmctl(unit, 0, DMGET) & DML_CAR) || (dev & SOFTCAR))
     176:         tp->t_state |= TS_CARR_ON;
     177:     while   ((tp->t_state & TS_CARR_ON) == 0 && !(flag & O_NONBLOCK))
     178:         {
     179:         tp->t_state |= TS_WOPEN;
     180:         sleep((caddr_t)&tp->t_rawq, TTIPRI);
     181:         }
     182:     error = (*linesw[tp->t_line].l_open)(dev, tp);
     183: out:
     184:     splx(s);
     185:     return(error);
     186:     }
     187:
     188: /*
     189:  * Close a DH line, turning off the DM11.
     190:  */
     191: dhclose(dev, flag)
     192:     dev_t   dev;
     193:     int flag;
     194:     {
     195:     register struct tty *tp;
     196:     register int    unit;
     197:
     198:     unit = UNIT(dev);
     199:     tp = &dh11[unit];
     200:     if  ((tp->t_state & (TS_WOPEN | TS_ISOPEN)) == 0)
     201:         return(EBADF);      /* XXX */
     202:     (*linesw[tp->t_line].l_close)(tp, flag);
     203:     ((struct dhdevice *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
     204:     dmctl(unit, DML_OFF, DMSET);
     205:     ttyclose(tp);
     206:     if  (dh_overrun[unit])
     207:         {
     208:         log(LOG_NOTICE, "dh%d %d overruns\n", dh_overrun[unit]);
     209:         dh_overrun[unit] = 0;
     210:         }
     211:     return(0);
     212:     }
     213:
     214: dhselect(dev, rw)
     215:     dev_t   dev;
     216:     int rw;
     217:     {
     218:     return(ttyselect(&dh11[UNIT(dev)], rw));
     219:     }
     220:
     221: dhread(dev, uio, flag)
     222:     dev_t dev;
     223:     struct uio *uio;
     224:     int flag;
     225:     {
     226:     register struct tty *tp = &dh11[UNIT(dev)];
     227:
     228:     return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
     229:     }
     230:
     231: dhwrite(dev, uio, flag)
     232:     dev_t dev;
     233:     struct uio *uio;
     234:     {
     235:     register struct tty *tp = &dh11[UNIT(dev)];
     236:
     237:     return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
     238:     }
     239:
     240: /*
     241:  * DH11 receiver interrupt.
     242:  */
     243: dhrint(dh)
     244:     int dh;
     245: {
     246:     register struct tty *tp;
     247:     register int c;
     248:     register struct dhdevice *addr;
     249:     struct tty *tp0;
     250:     int line, p;
     251:
     252:     addr = (struct dhdevice *)dhinfo[dh].ui_addr;
     253:     if  (addr == 0)     /* Can't happen? */
     254:         return;
     255:     tp0 = &dh11[dh<<4];
     256:     /*
     257: 	 * Loop fetching characters from the silo for this
     258: 	 * dh until there are no more in the silo.
     259: 	 */
     260:     while ((c = addr->dhrcr) < 0) {
     261:         line = (c >> 8) & 0xf;
     262:         tp = tp0 + line;
     263:         dhchars[dh]++;
     264:         if ((tp->t_state&TS_ISOPEN)==0) {
     265:             wakeup((caddr_t)&tp->t_rawq);
     266:             continue;
     267:         }
     268:         if  (c & DH_PE)
     269:             {
     270:             p =  tp->t_flags & (EVENP|ODDP);
     271:             if  (p == EVENP || p == ODDP)
     272:                 continue;
     273:             }
     274:         if  (c & DH_DO)
     275:             {
     276:             dh_overrun[(dh << 4) + line]++;
     277:             continue;
     278:             }
     279:         if (c & DH_FE)
     280:             /*
     281: 			 * At framing error (break) generate
     282: 			 * a null (in raw mode, for getty), or an
     283: 			 * interrupt (in cooked/cbreak mode).
     284: 			 */
     285:             if (tp->t_flags & RAW)
     286:                 c = 0;
     287:             else
     288: #ifdef  OLDWAY
     289:                 c = tp->t_intrc;
     290: #else
     291:                 c = tp->t_brkc; /* why have brkc if not used? */
     292: #endif
     293: #if NBK > 0
     294:         if (tp->t_line == NETLDISC) {
     295:             c &= 0177;
     296:             BKINPUT(c, tp);
     297:         } else
     298: #endif
     299:             (*linesw[tp->t_line].l_rint)(c, tp);
     300:     }
     301: }
     302:
     303: /*
     304:  * Ioctl for DH11.
     305:  */
     306: /*ARGSUSED*/
     307: dhioctl(dev, cmd, data, flag)
     308:     dev_t   dev;
     309:     u_int cmd;
     310:     caddr_t data;
     311:     int flag;
     312:     {
     313:     register struct tty *tp;
     314:     register unit = UNIT(dev);
     315:     int error, brkline;
     316:
     317:     tp = &dh11[unit];
     318:     error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
     319:     if  (error >= 0)
     320:         return(error);
     321:     error = ttioctl(tp, cmd, data, flag);
     322:     if  (error >= 0)
     323:         {
     324:         if  (cmd == TIOCSETP || cmd == TIOCSETN ||
     325:              cmd == TIOCLBIS || cmd == TIOCLBIC || cmd == TIOCLSET)
     326:             dhparam(unit);
     327:         return(error);
     328:         }
     329:     brkline = 1 << (unit & 0xf);
     330:     switch  (cmd)
     331:         {
     332:         case    TIOCSBRK:
     333:             ((struct dhdevice *)(tp->t_addr))->dhbreak |= brkline;
     334:             break;
     335:         case    TIOCCBRK:
     336:             ((struct dhdevice *)(tp->t_addr))->dhbreak &= ~brkline;
     337:             break;
     338:         case    TIOCSDTR:
     339:             (void)dmctl(unit, DML_DTR|DML_RTS, DMBIS);
     340:             break;
     341:         case    TIOCCDTR:
     342:             (void)dmctl(unit, DML_DTR|DML_RTS, DMBIC);
     343:             break;
     344:         case    TIOCMSET:
     345:             (void)dmctl(unit, dmtodh(*(int *)data, DMSET));
     346:             break;
     347:         case    TIOCMBIS:
     348:             (void)dmctl(unit, dmtodh(*(int *)data, DMBIS));
     349:             break;
     350:         case    TIOCMBIC:
     351:             (void)dmctl(unit, dmtodh(*(int *)data, DMBIC));
     352:             break;
     353:         case    TIOCMGET:
     354:             *(int *)data = dhtodm(dmctl(unit, 0, DMGET));
     355:             break;
     356:         default:
     357:             return(ENOTTY);
     358:         }
     359:     return(0);
     360:     }
     361:
     362: static  int
     363: dmtodh(bits)
     364:     register int bits;
     365:     {
     366:     register int    b = 0;
     367:
     368:     if  (bits & TIOCM_RTS) b |= DML_RTS;
     369:     if  (bits & TIOCM_DTR) b |= DML_DTR;
     370:     if  (bits & TIOCM_LE) b |= DML_LE;
     371:     return(b);
     372:     }
     373:
     374: static  int
     375: dhtodm(bits)
     376:     register int bits;
     377:     {
     378:     register int b = 0;
     379:
     380:     if  (bits & DML_RNG) b |= TIOCM_RNG;
     381:     if  (bits & DML_CAR) b |= TIOCM_CAR;
     382:     if  (bits & DML_CTS) b |= TIOCM_CTS;
     383:     if  (bits & DML_RTS) b |= TIOCM_RTS;
     384:     if  (bits & DML_DTR) b |= TIOCM_DTR;
     385:     if  (bits & DML_LE)  b |= TIOCM_LE;
     386:     return(b);
     387:     }
     388:
     389: /*
     390:  * Set parameters from open or stty into the DH hardware
     391:  * registers.
     392:  */
     393: dhparam(unit)
     394:     register int unit;
     395:     {
     396:     register struct tty *tp;
     397:     register struct dhdevice *addr;
     398:     register int lpar;
     399:     int s;
     400:
     401:     tp = &dh11[unit];
     402:     addr = (struct dhdevice *)tp->t_addr;
     403:     /*
     404: 	 * Block interrupts so parameters will be set
     405: 	 * before the line interrupts.
     406: 	 */
     407:     s = spltty();
     408:     addr->un.dhcsrl = (unit&0xf)|DH_IE;
     409:     if  ((tp->t_ispeed)==0)
     410:         {
     411:         tp->t_state |= TS_HUPCLS;
     412:         dmctl(unit, DML_OFF, DMSET);
     413:         goto out;
     414:         }
     415:     lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
     416:     if ((tp->t_ispeed) == B134)
     417:         lpar |= BITS6|PENABLE|HDUPLX;
     418:     else if (tp->t_flags & (RAW|LITOUT|PASS8))
     419:         lpar |= BITS8;
     420:     else
     421:         lpar |= BITS7|PENABLE;
     422:     if ((tp->t_flags&EVENP) == 0)
     423:         lpar |= OPAR;
     424:     if ((tp->t_ospeed) == B110)
     425:         lpar |= TWOSB;
     426:     addr->dhlpr = lpar;
     427: out:
     428:     splx(s);
     429:     return(0);
     430:     }
     431:
     432: /*
     433:  * DH transmitter interrupt.
     434:  * Restart each line which used to be active but has
     435:  * terminated transmission since the last interrupt.
     436:  */
     437: dhxint(dh)
     438:     int dh;
     439: {
     440:     register struct tty *tp;
     441:     register struct dhdevice *addr;
     442:     short ttybit, bar, *sbar;
     443:     register int unit;
     444:     u_short cntr;
     445:     ubadr_t car;
     446:     struct dmdevice *dmaddr;
     447:
     448:     addr = (struct dhdevice *)dhinfo[dh].ui_addr;
     449:     if (addr->un.dhcsr & DH_NXM) {
     450:         addr->un.dhcsr |= DH_CNI;
     451:         log(LOG_NOTICE, "dh%d NXM\n", dh);
     452:     }
     453:     sbar = &dhsar[dh];
     454:     bar = *sbar & ~addr->dhbar;
     455:     unit = dh * 16; ttybit = 1;
     456:     addr->un.dhcsr &= (short)~DH_TI;
     457:     for(; bar; unit++, ttybit <<= 1) {
     458:         if(bar & ttybit) {
     459:             *sbar &= ~ttybit;
     460:             bar &= ~ttybit;
     461:             tp = &dh11[unit];
     462:             tp->t_state &= ~TS_BUSY;
     463:             if (tp->t_state&TS_FLUSH)
     464:                 tp->t_state &= ~TS_FLUSH;
     465:             else {
     466:                 addr->un.dhcsrl = (unit&017)|DH_IE;
     467:                 /*
     468: 				 * Clists are either:
     469: 				 *	1)  in kernel virtual space,
     470: 				 *	    which in turn lies in the
     471: 				 *	    first 64K of physical memory or
     472: 				 *	2)  at UNIBUS virtual address 0.
     473: 				 *
     474: 				 * In either case, the extension bits are 0.
     475: 				 */
     476:                 car = (ubadr_t)addr->dhcar;
     477:                 if (!ubmap) {
     478: #if defined(CS02)
     479:                     dmaddr = (struct dmdevice *)dminfo[dh].ui_addr;
     480:
     481:                     car |= ((ubadr_t)(dmaddr->dmlst_h&077) << 16);
     482: #else
     483:                     car |= (ubadr_t)((addr->dhsilo & 0300) << 10);
     484: #endif
     485:                 }
     486:             cntr = car - cpaddr(tp->t_outq.c_cf);
     487:             ndflush(&tp->t_outq, cntr);
     488:             }
     489:             if (tp->t_line)
     490:                 (*linesw[tp->t_line].l_start)(tp);
     491:             else
     492:                 dhstart(tp);
     493:         }
     494:     }
     495: }
     496:
     497: /*
     498:  * Start (restart) transmission on the given DH11 line.
     499:  */
     500: dhstart(tp)
     501:     register struct tty *tp;
     502: {
     503:     register struct dhdevice *addr;
     504:     register int dh, unit, nch;
     505:     int s, csrl;
     506:     ubadr_t uba;
     507:     struct dmdevice *dmaddr;
     508:
     509:     unit = UNIT(tp->t_dev);
     510:     dh = unit >> 4;
     511:     unit &= 0xf;
     512:     addr = (struct dhdevice *)tp->t_addr;
     513:
     514:     /*
     515: 	 * Must hold interrupts in following code to prevent
     516: 	 * state of the tp from changing.
     517: 	 */
     518:     s = spltty();
     519:     /*
     520: 	 * If it's currently active, or delaying, no need to do anything.
     521: 	 */
     522:     if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
     523:         goto out;
     524:     ttyowake(tp);       /* Wake up any sleepers */
     525:     /*
     526: 	 * Now restart transmission unless the output queue is
     527: 	 * empty.
     528: 	 */
     529:     if (tp->t_outq.c_cc == 0)
     530:         goto out;
     531: /*
     532:  * This is where any per character delay handling would be done if ever
     533:  * implemented again.  See the comments in dhv.c and dhu.c
     534: */
     535:     nch = ndqb(&tp->t_outq, 0);
     536:     /*
     537: 	 * If characters to transmit, restart transmission.
     538: 	 */
     539:     if (nch) {
     540:         uba = cpaddr(tp->t_outq.c_cf);
     541:         csrl = (unit&017) | DH_IE;
     542:         if (ubmap)
     543:             addr->un.dhcsrl = (char)csrl;
     544:         else {
     545: #if defined(CS02)
     546:             dmaddr = (struct dmdevice *)dminfo[dh].ui_addr;
     547:             addr->un.dhcsrl = csrl;
     548:             dmaddr->dmlst_h = hiint(uba) & 077;
     549: #else
     550:             addr->un.dhcsrl = csrl | DH_IE | ((hiint(uba)<<4)&060);
     551: #endif
     552:         }
     553:         addr->dhcar = loint(uba);
     554:
     555:         { short word = 1 << unit;
     556:         dhsar[dh] |= word;
     557:         addr->dhbcr = -nch;
     558:         addr->dhbar |= word;
     559:         }
     560:         tp->t_state |= TS_BUSY;
     561:     }
     562: out:
     563:     splx(s);
     564: }
     565:
     566:
     567: /*
     568:  * Stop output on a line, e.g. for ^S/^Q or output flush.
     569:  */
     570: /*ARGSUSED*/
     571: dhstop(tp, flag)
     572:     register struct tty *tp;
     573: {
     574:     register struct dhdevice *addr;
     575:     register int unit, s;
     576:
     577:     addr = (struct dhdevice *)tp->t_addr;
     578:     /*
     579: 	 * Block input/output interrupts while messing with state.
     580: 	 */
     581:     s = spltty();
     582:     if (tp->t_state & TS_BUSY) {
     583:         /*
     584: 		 * Device is transmitting; stop output
     585: 		 * by selecting the line and setting the byte
     586: 		 * count to -1.  We will clean up later
     587: 		 * by examining the address where the dh stopped.
     588: 		 */
     589:         unit = UNIT(tp->t_dev);
     590:         addr->un.dhcsrl = (unit&017) | DH_IE;
     591:         if ((tp->t_state & TS_TTSTOP) == 0) {
     592:             tp->t_state |= TS_FLUSH;
     593:         }
     594:         addr->dhbcr = -1;
     595:     }
     596:     splx(s);
     597: }
     598:
     599: int dhtransitions, dhslowtimers, dhfasttimers;      /*DEBUG*/
     600: /*
     601:  * At software clock interrupt time, check status.
     602:  * Empty all the dh silos that are in use, and decide whether
     603:  * to turn any silos off or on.
     604:  */
     605: dhtimer()
     606: {
     607:     register int dh, s;
     608:     static int timercalls;
     609:
     610:     if (dhsilos) {
     611:         dhfasttimers++;     /*DEBUG*/
     612:         timercalls++;
     613:         s = spltty();
     614:         for (dh = 0; dh < NDH; dh++)
     615:             if (dhsilos & (1 << dh))
     616:                 dhrint(dh);
     617:         splx(s);
     618:     }
     619:     if ((dhsilos == 0) || ((timercalls += FASTTIMER) >= hz)) {
     620:         dhslowtimers++;     /*DEBUG*/
     621:         timercalls = 0;
     622:         for (dh = 0; dh < NDH; dh++) {
     623:             ave(dhrate[dh], dhchars[dh], 8);
     624:             if ((dhchars[dh] > dhhighrate) &&
     625:               ((dhsilos & (1 << dh)) == 0)) {
     626:             ((struct dhdevice *)(dhinfo[dh].ui_addr))->dhsilo =
     627:                 (dhchars[dh] > 500? 32 : 16);
     628:             dhsilos |= (1 << dh);
     629:             dhtransitions++;        /*DEBUG*/
     630:             } else if ((dhsilos & (1 << dh)) &&
     631:               (dhrate[dh] < dhlowrate)) {
     632:             ((struct dhdevice *)(dhinfo[dh].ui_addr))->dhsilo = 0;
     633:             dhsilos &= ~(1 << dh);
     634:             }
     635:             dhchars[dh] = 0;
     636:         }
     637:     }
     638:     timeout(dhtimer, (caddr_t) 0, dhsilos ? FASTTIMER : hz);
     639: }
     640:
     641: /*
     642:  * Turn on the line associated with dh dev.
     643:  */
     644: dmopen(dev)
     645:     dev_t dev;
     646:     {
     647:     register struct tty *tp;
     648:     register struct dmdevice *addr;
     649:     register int unit;
     650:     int dm;
     651:
     652:     unit = UNIT(dev);
     653:     dm = unit >> 4;
     654:     tp = &dh11[unit];
     655:     if  (dm >= NDH || dminfo[dm].ui_alive == 0)
     656:         {
     657:         tp->t_state |= TS_CARR_ON;
     658:         return;
     659:         }
     660:     (void)dmctl(unit, DML_ON, DMSET);
     661:     }
     662:
     663: /*
     664:  * Dump control bits into the DM registers.
     665:  */
     666: dmctl(unit, bits, how)
     667:     int unit;
     668:     int bits, how;
     669:     {
     670:     register struct dmdevice *addr;
     671:     register int s, mbits;
     672:     int dm;
     673:
     674:     dm = unit >> 4;
     675:     addr = (struct dmdevice *)dminfo[dm].ui_addr;
     676:     if  (!addr)
     677:         return(0);
     678:     s = spltty();
     679:     addr->dmcsr &= ~DM_SE;
     680:     while   (addr->dmcsr & DM_BUSY)
     681:         ;
     682:     addr->dmcsr = unit & 0xf;
     683:     mbits = addr->dmlstat;
     684:
     685:     switch  (how)
     686:         {
     687:         case    DMGET:
     688:             break;      /* go re-enable scan */
     689:         case    DMSET:
     690:             mbits = bits;
     691:             break;
     692:         case    DMBIS:
     693:             mbits |= bits;
     694:             break;
     695:         case    DMBIC:
     696:             mbits &= ~bits;
     697:             break;
     698:         }
     699:     addr->dmlstat = mbits;
     700:     addr->dmcsr = DM_IE|DM_SE;
     701:     splx(s);
     702:     return(mbits);
     703:     }
     704:
     705: /*
     706:  * DM interrupt; deal with carrier transitions.
     707:  */
     708: dmintr(dm)
     709:     int dm;
     710:     {
     711:     register struct uba_device *ui;
     712:     register struct tty *tp;
     713:     register struct dmdevice *addr;
     714:     int unit;
     715:
     716:     ui = &dminfo[dm];
     717:     addr = (struct dmdevice *)ui->ui_addr;
     718:     if  (addr->dmcsr&DM_DONE == 0)
     719:         return;
     720:     unit = addr->dmcsr & 0xf;
     721:     tp = &dh11[(dm << 4) + unit];
     722:     if  (addr->dmcsr & DM_CF)
     723:         {
     724:         if  (addr->dmlstat & DML_CAR)
     725:             (void)(*linesw[tp->t_line].l_modem)(tp, 1);
     726:         else if (!(tp->t_dev & SOFTCAR) &&
     727:               (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
     728:             addr->dmlstat = 0;
     729:         }
     730:     if  (addr->dmcsr & DM_CTS)
     731:         {
     732:         if  (tp->t_flags & RTSCTS)
     733:             {
     734:             if  (addr->dmlstat & DML_CTS)
     735:                 {
     736:                 tp->t_state &= ~TS_TTSTOP;
     737:                 ttstart(tp);
     738:                 }
     739:             else
     740:                 {
     741:                 tp->t_state |= TS_TTSTOP;
     742:                 dhstop(tp, 0);
     743:                 }
     744:             }
     745:         }
     746:     addr->dmcsr = DM_IE|DM_SE;
     747:     }
     748: #endif

#### Defined functions

dhattach defined in line 83; never used
dhclose defined in line 191; never used
dhioctl defined in line 307; never used
dhopen defined in line 121; never used
dhparam defined in line 393; used 2 times

- in line 167, 326

dhread defined in line 221; never used
dhrint defined in line 243; used 2 times

- in line 616
- in /usr/src/sys/pdp/scb.s line 384

dhselect defined in line 214; never used
dhstart defined in line 500; used 3 times

- in line 66, 137, 492

dhstop defined in line 571; used 1 times

- in line 742

dhtimer defined in line 605; used 3 times

- in line 36, 142, 638

dhtodm defined in line 374; used 2 times

- in line 67, 354

dhwrite defined in line 231; never used
dhxint defined in line 437; used 1 times

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

dmattach defined in line 100; never used
dmctl defined in line 666; used 10 times

- in line 175, 204, 339-354(6), 412, 660

dmintr defined in line 708; used 1 times

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

dmopen defined in line 644; used 1 times

- in line 174

dmtodh defined in line 362; used 4 times

- in line 67, 345-351(3)

#### Defined variables

dh11 defined in line 54; used 11 times

- in line 134, 199, 218, 226, 235, 255, 317, 401, 461, 654, 721

dh_overrun defined in line 55; used 4 times

- in line 206-209(3), 276

dhact defined in line 59; used 2 times

- in line 144-147(2)

dhchars defined in line 61; used 5 times

- in line 263, 623-627(3), 635

dhfasttimers defined in line 599; used 1 times

- in line 611

dhhighrate defined in line 63; used 1 times

- in line 624

dhinfo defined in line 37; used 7 times

- in line 89-90(2), 132, 252, 448, 626, 632

dhlowrate defined in line 64; used 1 times

- in line 631

dhrate defined in line 62; used 2 times

- in line 623, 631

dhsar defined in line 52; used 2 times

- in line 453, 556

dhsilos defined in line 60; used 8 times

- in line 610-619(3), 625-638(5)

dhslowtimers defined in line 599; used 1 times

- in line 620

dhtransitions defined in line 599; used 1 times

- in line 629

dminfo defined in line 38; used 7 times

- in line 106-107(2), 479, 546, 655, 675, 716

ndh11 defined in line 58; never used
timerstarted defined in line 65; used 2 times

- in line 139-141(2)

#### Defined macros

FASTTIMER defined in line 47; used 2 times

- in line 619, 638

HWFLOW defined in line 78; used 1 times

- in line 163

IFLAGS defined in line 40; used 1 times

- in line 159

SOFTCAR defined in line 77; used 2 times

- in line 175, 726

UNIT defined in line 76; used 9 times

- in line 130, 198, 218, 226, 235, 314, 509, 589, 652

cpaddr defined in line 73; used 2 times

- in line 486, 540

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