1: /*
   2:  *	DH-11 driver
   3:  *	This driver calls on the DHDM driver.
   4:  *	If the DH has no DM11-BB, then the latter will
   5:  *	be fake. To insure loading of the correct DM code,
   6:  *	lib2 should have dhdm.o, dh.o and dhfdm.o in that order.
   7:  */
   8: 
   9: #include "../h/param.h"
  10: #include "../h/conf.h"
  11: #include "../h/dir.h"
  12: #include "../h/user.h"
  13: #include "../h/tty.h"
  14: 
  15: #define q3  tp->t_outq
  16: #define DHADDR  ((struct device *)0160020)
  17: #define NDH11   16  /* number of lines */
  18: 
  19: struct  tty dh11[NDH11];
  20: char    dhcc[NDH11];
  21: int dhchars[(NDH11+15)/16];
  22: int ndh11   = NDH11;
  23: int dhstart();
  24: int ttrstrt();
  25: 
  26: /*
  27:  * Hardware control bits
  28:  */
  29: #define BITS6   01
  30: #define BITS7   02
  31: #define BITS8   03
  32: #define TWOSB   04
  33: #define PENABLE 020
  34: /* DEC manuals incorrectly say this bit causes generation of even parity. */
  35: #define OPAR    040
  36: #define HDUPLX  040000
  37: 
  38: #define IENAB   030100
  39: #define PERROR  010000
  40: #define FRERROR 020000
  41: #define OVERRUN 040000
  42: #define XINT    0100000
  43: #define SSPEED  7   /* standard speed: 300 baud */
  44: #define NSILO   16
  45: #define DHTIME  6
  46: extern int dhtimer();
  47: 
  48: /*
  49:  * DM control bits
  50:  */
  51: #define TURNON  03  /* CD lead + line enable */
  52: #define TURNOFF 01  /* line enable */
  53: #define RQS 04  /* request to send */
  54: 
  55: /*
  56:  * Software copy of last dhbar
  57:  */
  58: int dhsar[(NDH11+15)/16];
  59: 
  60: struct device
  61: {
  62:     union {
  63:         int dhcsr;
  64:         char    dhcsrl;
  65:     } un;
  66:     int dhnxch;
  67:     int dhlpr;
  68:     char    *dhcar;
  69:     int dhbcr;
  70:     int dhbar;
  71:     int dhbreak;
  72:     int dhsilo;
  73: };
  74: 
  75: /*
  76:  * Open a DH11 line.
  77:  */
  78: dhopen(dev, flag)
  79: {
  80:     register struct tty *tp;
  81:     register d;
  82:     register struct device *addr;
  83:     static  timer_on;
  84:     int s;
  85: 
  86:     d = minor(dev);
  87:     if (d >= NDH11) {
  88:         u.u_error = ENXIO;
  89:         return;
  90:     }
  91:     tp = &dh11[d];
  92:     addr = DHADDR;
  93:     addr += d>>4;
  94:     tp->t_addr = (caddr_t)addr;
  95:     tp->t_oproc = dhstart;
  96:     tp->t_iproc = NULL;
  97:     tp->t_state |= WOPEN;
  98:     s = spl6();
  99:     if (!timer_on) {
 100:         timer_on++;
 101:         timeout(dhtimer, (caddr_t)0, DHTIME);
 102:     }
 103:     splx(s);
 104:     addr->un.dhcsr |= IENAB;
 105:     if ((tp->t_state&ISOPEN) == 0) {
 106:         ttychars(tp);
 107:         tp->t_ispeed = SSPEED;
 108:         tp->t_ospeed = SSPEED;
 109:         tp->t_flags = ODDP|EVENP|ECHO;
 110:         dhparam(d);
 111:     }
 112:     if (tp->t_state&XCLUDE && u.u_uid!=0) {
 113:         u.u_error = EBUSY;
 114:         return;
 115:     }
 116:     dmopen(d);
 117:     (*linesw[tp->t_line].l_open)(dev,tp);
 118: }
 119: 
 120: /*
 121:  * Close a DH11 line.
 122:  */
 123: dhclose(dev, flag)
 124: dev_t dev;
 125: int  flag;
 126: {
 127:     register struct tty *tp;
 128:     register d;
 129: 
 130:     d = minor(dev);
 131:     tp = &dh11[d];
 132:     (*linesw[tp->t_line].l_close)(tp);
 133:     if (tp->t_state&HUPCLS)
 134:         dmctl(d, TURNOFF);
 135:     ttyclose(tp);
 136: }
 137: 
 138: /*
 139:  * Read from a DH11 line.
 140:  */
 141: dhread(dev)
 142: {
 143: register struct tty *tp;
 144: 
 145:     tp = &dh11[minor(dev)];
 146:     (*linesw[tp->t_line].l_read)(tp);
 147: }
 148: 
 149: /*
 150:  * write on a DH11 line
 151:  */
 152: dhwrite(dev)
 153: {
 154: register struct tty *tp;
 155: 
 156:     tp = &dh11[minor(dev)];
 157:     (*linesw[tp->t_line].l_write)(tp);
 158: }
 159: 
 160: /*
 161:  * DH11 receiver interrupt.
 162:  */
 163: dhrint(dev)
 164: {
 165:     register struct tty *tp;
 166:     register int c;
 167:     register struct device *addr;
 168: 
 169:     addr = DHADDR;
 170:     addr += minor(dev);
 171:     while ((c = addr->dhnxch) < 0) {    /* char. present */
 172:         tp = &dh11[(minor(dev)<<4) + ((c>>8)&017)];
 173:         dhchars[minor(dev)]++;
 174:         if (tp >= &dh11[NDH11])
 175:             continue;
 176:         if((tp->t_state&ISOPEN)==0) {
 177:             wakeup((caddr_t)tp);
 178:             continue;
 179:         }
 180:         if (c&PERROR)
 181:             if ((tp->t_flags&(EVENP|ODDP))==EVENP
 182:              || (tp->t_flags&(EVENP|ODDP))==ODDP )
 183:                 continue;
 184:         if (c&FRERROR)      /* break */
 185:             if (tp->t_flags&RAW)
 186:                 c = 0;  /* null (for getty) */
 187:             else
 188:                 c = 0177;   /* DEL (intr) */
 189:         (*linesw[tp->t_line].l_rint)(c,tp);
 190:     }
 191: }
 192: 
 193: /*
 194:  * stty/gtty for DH11
 195:  */
 196: dhioctl(dev, cmd, addr, flag)
 197: caddr_t addr;
 198: {
 199:     register struct tty *tp;
 200: 
 201:     tp = &dh11[minor(dev)];
 202:     if (ttioccomm(cmd, tp, addr, dev)) {
 203:         if (cmd==TIOCSETP||cmd==TIOCSETN)
 204:             dhparam(dev);
 205:     } else
 206:         u.u_error = ENOTTY;
 207: }
 208: 
 209: /*
 210:  * Set parameters from open or stty into the DH hardware
 211:  * registers.
 212:  */
 213: dhparam(dev)
 214: {
 215:     register struct tty *tp;
 216:     register struct device *addr;
 217:     register d;
 218: 
 219:     d = minor(dev);
 220:     tp = &dh11[d];
 221:     addr = (struct device *)tp->t_addr;
 222:     spl5();
 223:     addr->un.dhcsrl = (d&017) | IENAB;
 224:     /*
 225: 	 * Hang up line?
 226: 	 */
 227:     if ((tp->t_ispeed)==0) {
 228:         tp->t_state |= HUPCLS;
 229:         dmctl(d, TURNOFF);
 230:         return;
 231:     }
 232:     d = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
 233:     if ((tp->t_ispeed) == 4)        /* 134.5 baud */
 234:         d |= BITS6|PENABLE|HDUPLX;
 235:     else if (tp->t_flags&RAW)
 236:         d |= BITS8;
 237:     else
 238:         d |= BITS7|PENABLE;
 239:     if ((tp->t_flags&EVENP) == 0)
 240:         d |= OPAR;
 241:     if ((tp->t_ospeed) == 3)    /* 110 baud */
 242:         d |= TWOSB;
 243:     addr->dhlpr = d;
 244:     spl0();
 245: }
 246: 
 247: /*
 248:  * DH11 transmitter interrupt.
 249:  * Restart each line which used to be active but has
 250:  * terminated transmission since the last interrupt.
 251:  */
 252: dhxint(dev)
 253: {
 254:     register struct tty *tp;
 255:     register struct device *addr;
 256:     register d;
 257:     int ttybit, bar, *sbar;
 258: 
 259:     d = minor(dev);
 260:     addr = DHADDR + d;
 261:     addr->un.dhcsr &= ~XINT;
 262:     sbar = &dhsar[d];
 263:     bar = *sbar & ~addr->dhbar;
 264:     d <<= 4; ttybit = 1;
 265: 
 266:     for(; bar; d++, ttybit <<= 1) {
 267:         if(bar&ttybit) {
 268:             *sbar &= ~ttybit;
 269:             bar &= ~ttybit;
 270:             tp = &dh11[d];
 271:             if (tp->t_line) {
 272:                 (*linesw[tp->t_line].l_start)(tp);
 273:             } else {
 274:                 addr->un.dhcsrl = (d&017)|IENAB;
 275:                 if (tp->t_state&FLUSH)
 276:                     tp->t_state &= ~FLUSH;
 277:                 else {
 278:                     ndflush(&q3, addr->dhcar-q3.c_cf);
 279:                 }
 280:                 tp->t_state &= ~BUSY;
 281:                 dhstart(tp);
 282:             }
 283:         }
 284:     }
 285: }
 286: 
 287: /*
 288:  * Start (restart) transmission on the given DH11 line.
 289:  */
 290: dhstart(tp)
 291: register struct tty *tp;
 292: {
 293:     register struct device *addr;
 294:     register nch;
 295:     int s, d;
 296: 
 297:     /*
 298: 	 * If it's currently active, or delaying,
 299: 	 * no need to do anything.
 300: 	 */
 301:     s = spl5();
 302:     d = tp-dh11;
 303:     addr = (struct device *)tp->t_addr;
 304:     if (tp->t_state&(TIMEOUT|BUSY|TTSTOP))
 305:         goto out;
 306: 
 307: 
 308:     /*
 309: 	 * If the writer was sleeping on output overflow,
 310: 	 * wake him when low tide is reached.
 311: 	 */
 312:     if (tp->t_state&ASLEEP && tp->t_outq.c_cc<=TTLOWAT) {
 313:         tp->t_state &= ~ASLEEP;
 314:         if (tp->t_chan)
 315:             mcstart(tp->t_chan, (caddr_t)&tp->t_outq); else
 316:             wakeup((caddr_t)&tp->t_outq);
 317:     }
 318: 
 319:     if (tp->t_outq.c_cc == 0)
 320:         goto out;
 321: 
 322: 
 323: 
 324:     /*
 325: 	 * Find number of characters to transfer.
 326: 	 */
 327:     if (tp->t_flags & RAW) {
 328:         nch = ndqb(&tp->t_outq, 0);
 329:     } else {
 330:         nch = ndqb(&tp->t_outq, 0200);
 331:         if (nch == 0) {
 332:             nch = getc(&tp->t_outq);
 333:             timeout(ttrstrt, (caddr_t)tp, (nch&0177)+6);
 334:             tp->t_state |= TIMEOUT;
 335:             goto out;
 336:         }
 337:     }
 338:     /*
 339: 	 * If any characters were set up, start transmission;
 340: 	 */
 341:     if (nch) {
 342:         addr->un.dhcsrl = (d&017)|IENAB;
 343:         addr->dhcar = tp->t_outq.c_cf;
 344:         addr->dhbcr = -nch;
 345:         dhcc[d] = nch;
 346:         nch = 1<<(d&017);
 347:         addr->dhbar |= nch;
 348:         dhsar[d>>4] |= nch;
 349:         tp->t_state |= BUSY;
 350:     }
 351:     out:
 352:     splx(s);
 353: }
 354: 
 355: 
 356: /*
 357:  * Stop output on a line.
 358:  */
 359: dhstop(tp, flag)
 360: register struct tty *tp;
 361: {
 362:     register struct device *addr;
 363:     register d, s;
 364: 
 365:     addr = (struct device *)tp->t_addr;
 366:     s = spl6();
 367:     if (tp->t_state & BUSY) {
 368:         d = minor(tp->t_dev);
 369:         addr->un.dhcsrl = (d&017) | IENAB;
 370:         if ((tp->t_state&TTSTOP)==0) {
 371:             tp->t_state |= FLUSH;
 372:         }
 373:         addr->dhbcr = -1;
 374:     }
 375:     splx(s);
 376: }
 377: 
 378: dhtimer(dev)
 379: {
 380: register d,cc;
 381: register struct device *addr;
 382: 
 383:     addr = DHADDR; d = 0;
 384:     do {
 385:         cc = dhchars[d];
 386:         dhchars[d] = 0;
 387:         if (cc > 50)
 388:             cc = 32; else
 389:             if (cc > 16)
 390:                 cc = 16; else
 391:                 cc = 0;
 392:         addr->dhsilo = cc;
 393:         addr += 1;
 394:         dhrint(d++);
 395:     } while (d < (NDH11+15)/16);
 396:     timeout(dhtimer, (caddr_t)0, DHTIME);
 397: }

Defined functions

dhclose defined in line 123; never used
dhioctl defined in line 196; never used
dhopen defined in line 78; never used
dhparam defined in line 213; used 3 times
dhread defined in line 141; never used
dhrint defined in line 163; used 1 times
dhstart defined in line 290; used 3 times
dhstop defined in line 359; never used
dhtimer defined in line 378; used 3 times
dhwrite defined in line 152; never used
dhxint defined in line 252; never used

Defined variables

dh11 defined in line 19; used 10 times
dhcc defined in line 20; used 1 times
dhchars defined in line 21; used 3 times
dhsar defined in line 58; used 2 times
ndh11 defined in line 22; never used

Defined struct's

device defined in line 60; used 20 times

Defined macros

BITS6 defined in line 29; used 1 times
BITS7 defined in line 30; used 1 times
BITS8 defined in line 31; used 1 times
DHADDR defined in line 16; used 4 times
DHTIME defined in line 45; used 2 times
FRERROR defined in line 40; used 1 times
HDUPLX defined in line 36; used 1 times
IENAB defined in line 38; used 5 times
NDH11 defined in line 17; used 8 times
NSILO defined in line 44; never used
OPAR defined in line 35; used 1 times
OVERRUN defined in line 41; never used
PENABLE defined in line 33; used 2 times
PERROR defined in line 39; used 1 times
RQS defined in line 53; never used
SSPEED defined in line 43; used 2 times
TURNOFF defined in line 52; used 2 times
TURNON defined in line 51; never used
TWOSB defined in line 32; used 1 times
XINT defined in line 42; used 1 times
q3 defined in line 15; used 2 times
  • in line 278(2)
Last modified: 1979-05-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1123
Valid CSS Valid XHTML 1.0 Strict