1: #
   2: /*
   3:  */
   4: 
   5: /*
   6:  * DP-11 Synchronous interface driver
   7:  * This driver is rather insensitive to the remote
   8:  * device it talks to, which is to say most of the protocol
   9:  * must be supplied by the calling program.
  10:  * Exceptions: parity is even; 7 data bits per character;
  11:  * max. of 512 characters per record; 10 second timeout
  12:  * on waiting to receive; half-duplex transmission.
  13:  */
  14: 
  15: #include "../param.h"
  16: #include "../conf.h"
  17: #include "../user.h"
  18: #include "../buf.h"
  19: 
  20: /* control info */
  21: struct {
  22:     char    *dp_buf;
  23:     char    *dp_bufp;
  24:     int dp_nxmit;
  25:     char    dp_state;
  26:     char    dp_timer;
  27:     int dp_proc;
  28: } dp11;
  29: 
  30: /* device registers */
  31: struct {
  32:     int dprcsr;
  33:     char    dprbuf;
  34:     char    dpsyn0;
  35:     int dptcsr;
  36:     char    dptbuf;
  37:     char    dpsyn1;
  38: };
  39: 
  40: /* bits */
  41: #define ODDPAR  010000
  42: #define IENABLE 0100
  43: #define HDUPLX  02
  44: 
  45: #define CTRANS  0100000
  46: #define RORUN   040000
  47: #define RING    020000
  48: #define DSRDY   010000
  49: #define CARRIER 04000
  50: #define DONE    0200
  51: #define IENABLE 0100
  52: #define SIENABL 040
  53: 
  54: #define WRITE   1
  55: #define READ    0
  56: 
  57: #define DTRDY   01
  58: #define RCVACT  04000
  59: 
  60: #define DPADDR  0174770
  61: #define DPPRI   5
  62: #define SYN 026     /* (receive) sync character */
  63: 
  64: /*
  65:  * The open fails unless the device is not open or
  66:  * the opening process is the one that has it open already.
  67:  */
  68: dpopen(dev, flag)
  69: {
  70:     int dptimeout();
  71: 
  72:     if (dp11.dp_proc!=0 && dp11.dp_proc!=u.u_procp) {
  73:         u.u_error = ENXIO;
  74:         return;
  75:     }
  76:     dp11.dp_proc = u.u_procp;
  77:     dp11.dp_state = READ;
  78:     if (dp11.dp_buf==0) {
  79:         dp11.dp_buf = getblk(NODEV);
  80:         dp11.dp_bufp = dp11.dp_buf->b_addr;
  81:         dp11.dp_timer = HZ;
  82:         timeout(dptimeout, 0, HZ);
  83:     }
  84:     DPADDR->dpsyn0 = SYN;
  85:     DPADDR->dprcsr = HDUPLX|IENABLE;
  86:     DPADDR->dptcsr = IENABLE|SIENABL|DTRDY;
  87: }
  88: 
  89: dpclose()
  90: {
  91:     DPADDR->dprcsr = 0;
  92:     DPADDR->dptcsr = 0;
  93:     dp11.dp_timer = 0;
  94:     dp11.dp_proc = 0;
  95:     if (dp11.dp_buf != 0) {
  96:         brelse(dp11.dp_buf);
  97:         dp11.dp_buf = 0;
  98:     }
  99: }
 100: 
 101: /*
 102:  * Read waits until:
 103:  *  there is loss of "data set ready", or
 104:  *  a timeout occurs, or
 105:  *  a full record has been received.
 106:  * The former two result in an error.
 107:  */
 108: dpread()
 109: {
 110:     register char *bp, **epp;
 111: 
 112:     bp = dp11.dp_buf->b_addr;
 113:     epp = &dp11.dp_bufp;
 114:     for(;;) {
 115:         if(dpwait())
 116:             return;
 117:         if (*epp > bp)
 118:             break;
 119:         spl6();
 120:         if (dp11.dp_timer <= 1) {
 121:             spl0();
 122:             return;
 123:         }
 124:         sleep(&dp11, DPPRI);
 125:         spl0();
 126:     }
 127:     iomove(dp11.dp_buf, 0, min(u.u_count, *epp-bp), B_READ);
 128: }
 129: 
 130: /*
 131:  * write checks to make sure that the data set is not reading,
 132:  * and that it is ready.  Then the record is copied
 133:  * and transmission started.
 134:  */
 135: dpwrite()
 136: {
 137:     register char *bp;
 138: 
 139:     if (u.u_count==0 || dpwait())
 140:         return;
 141:     dp11.dp_state = WRITE;
 142:     bp = dp11.dp_buf->b_addr;
 143:     dp11.dp_bufp = bp;
 144:     if (u.u_count>512)
 145:         u.u_count = 512;
 146:     dp11.dp_nxmit = u.u_count;
 147:     iomove(dp11.dp_buf, 0, u.u_count, B_WRITE);
 148:     dpstart();
 149: }
 150: 
 151: /*
 152:  * If "data set ready" is down return an error; otherwise
 153:  * wait until the dataset is in read state with no carrier,
 154:  * which means a record has just been received.
 155:  */
 156: dpwait()
 157: {
 158:     for(;;) {
 159:         if ((DPADDR->dptcsr&DSRDY)==0 || dp11.dp_buf==0) {
 160:             u.u_error = EIO;
 161:             return(1);
 162:         }
 163:         spl6();
 164:         if (dp11.dp_state==READ && (DPADDR->dptcsr&CARRIER)==0) {
 165:             spl0();
 166:             return(0);
 167:         }
 168:         sleep(&dp11, DPPRI);
 169:         spl0();
 170:     }
 171: }
 172: 
 173: /*
 174:  * Start off the next character to be transmitted;
 175:  * when the record is done, drop back into read state.
 176:  */
 177: dpstart()
 178: {
 179:     register int c;
 180:     extern char partab[];
 181: 
 182:     dp11.dp_timer = 10;
 183:     if (--dp11.dp_nxmit >= 0) {
 184:         c = (*dp11.dp_bufp++) & 0177;
 185:         DPADDR->dptbuf = c | ~partab[c]&0200;
 186:     } else {
 187:         dp11.dp_bufp = dp11.dp_buf->b_addr;
 188:         dp11.dp_state = READ;
 189:     }
 190: }
 191: 
 192: /*
 193:  * Count down the DP timer (once per second)
 194:  * If it runs out, it presumably means the other station
 195:  * won't speak.
 196:  */
 197: dptimeout()
 198: {
 199:     if (dp11.dp_timer==0)
 200:         return;
 201:     if (--dp11.dp_timer==0) {
 202:         dpturnaround();
 203:         dp11.dp_timer = 1;
 204:     }
 205:     timeout(dptimeout, 0, HZ);
 206: }
 207: 
 208: /*
 209:  * Receiver interrupt: if reading, stash character
 210:  * unless there is an overrun.
 211:  */
 212: dprint()
 213: {
 214:     register int c;
 215: 
 216:     c = DPADDR->dprbuf & 0177;
 217:     if (dp11.dp_state==READ) {
 218:         if ((DPADDR->dprcsr&ODDPAR) == 0)
 219:             c =| 0200;
 220:         if (dp11.dp_bufp < dp11.dp_buf->b_addr+512)
 221:             *dp11.dp_bufp++ = c;
 222:     }
 223: }
 224: 
 225: /*
 226:  * Transmitter interrupt:
 227:  * Knock down hardware bits.
 228:  * If carrier has dropped, the record is done, so turn the line around;
 229:  * otherwise start another character.
 230:  */
 231: dpxint()
 232: {
 233:     register int dpstat;
 234: 
 235:     dpstat = DPADDR->dptcsr;
 236:     DPADDR->dptcsr =& ~(CTRANS|RORUN|RING|DONE);
 237:     if (dpstat & (CTRANS|RORUN))
 238:         dpturnaround();
 239:     else if (dpstat&DONE && dp11.dp_state==WRITE)
 240:         dpstart();
 241: }
 242: 
 243: /*
 244:  * Change the state from writing to reading at the end of a record.
 245:  */
 246: dpturnaround()
 247: {
 248:     DPADDR->dprcsr =& ~RCVACT;
 249:     if (dp11.dp_state==WRITE) {
 250:         dp11.dp_timer = 10;
 251:         dp11.dp_state = READ;
 252:         dp11.dp_bufp = dp11.dp_buf->b_addr;
 253:     }
 254:     wakeup(&dp11);
 255: }

Defined functions

dpclose defined in line 89; never used
dpopen defined in line 68; never used
dpread defined in line 108; never used
dprint defined in line 212; never used
dpstart defined in line 177; used 2 times
dptimeout defined in line 197; used 3 times
dpturnaround defined in line 246; used 2 times
dpwait defined in line 156; used 2 times
dpwrite defined in line 135; never used
dpxint defined in line 231; never used

Defined macros

CARRIER defined in line 49; used 1 times
CTRANS defined in line 45; used 2 times
DONE defined in line 50; used 2 times
DPADDR defined in line 60; used 13 times
DPPRI defined in line 61; used 2 times
DSRDY defined in line 48; used 1 times
DTRDY defined in line 57; used 1 times
  • in line 86
HDUPLX defined in line 43; used 1 times
  • in line 85
IENABLE defined in line 51; used 2 times
ODDPAR defined in line 41; used 1 times
RCVACT defined in line 58; used 1 times
READ defined in line 55; used 5 times
RING defined in line 47; used 1 times
RORUN defined in line 46; used 2 times
SIENABL defined in line 52; used 1 times
  • in line 86
SYN defined in line 62; used 1 times
  • in line 84
WRITE defined in line 54; used 3 times
Last modified: 1975-07-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1155
Valid CSS Valid XHTML 1.0 Strict