1: #define KERNEL 1
2: #include "../h/pk.p"
3:
4: /*
5: * input framing and block checking.
6: * frame layout for most devices is:
7: *
8: * S|K|X|Y|C|Z| ... data ... |
9: *
10: * where S == initial synch byte
11: * K == encoded frame size (indexes pksizes[])
12: * X, Y == block check bytes
13: * C == control byte
14: * Z == XOR of header (K^X^Y^C)
15: * data == 0 or more data bytes
16: *
17: * device driver interfaces on input are:
18: * pkrint - byte level
19: * pkrend - dma or pseudo-dma transfer level
20: * pkdata - packet level
21: */
22:
23: int pksizes[] ={
24: 1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1
25: };
26:
27: /*
28: * Pseudo-dma byte collection.
29: * This code can be put in the device driver
30: * interrupt routine to eliminate the per byte
31: * subroutine call.
32: */
33: pkrint(c, tp)
34: register c;
35: register struct tty *tp;
36: {
37:
38: if (q1.c_cc<0) {
39: if (q1.c_cf != NULL) {
40: tp->t_erase = 0;
41: *q1.c_cf++ = c;
42: }
43: if (++q1.c_cc)
44: return;
45: pkrend(tp);
46: return;
47: }
48: }
49:
50:
51:
52: /*
53: * End of input transfer.
54: */
55: pkrend(tp)
56: register struct tty *tp;
57: {
58: register char *p;
59: struct pack *pk;
60: struct header *h;
61: register x;
62: char cntl, hdcheck;
63: unsigned short sum;
64: int i,j,k;
65: char **bp;
66:
67: p = q1.c_cl;
68: x = (int)q1.c_cf - (int)p;
69: pk = (struct pack *)tp->t_linep;
70: h = (struct header * )&pk->p_ihbuf;
71: if (x == HDRSIZ) {
72: if (*p++ == SYN ) {
73: hdcheck = k = *p++;
74: sum = (unsigned)*p;
75: hdcheck ^= *p++;
76: sum |= (unsigned)*p << 8;
77: hdcheck ^= *p++;
78: hdcheck ^= cntl = *p++;
79: if (hdcheck != *p) {
80: goto bad;
81: }
82: if (k == 9) {
83: pkcntl(cntl, pk);
84: q1.c_cf = q1.c_cl;
85: q1.c_cc = -HDRSIZ;
86: goto istart1;
87: }
88: if (k && pksizes[k]==pk->p_rsize) {
89: pk->p_rpr = cntl&MOD8;
90: pksack(pk);
91: bp = pk->p_ipool;
92: if (bp) {
93: pk->p_ipool = (char **)*bp;
94: pk->p_io = bp;
95: } else {
96: }
97: q1.c_cf = (char *)bp;
98: q1.c_cc = -pk->p_rsize;
99: h->sum = sum;
100: h->cntl = cntl;
101: goto istart1;
102: }
103: bad:
104: pkbadframe(pk);
105: }
106: scan:
107: x = HDRSIZ;
108: j = 0;
109: p = (caddr_t)h;
110: for (i = 1; i < HDRSIZ; i++)
111: if (p[i] == SYN)
112: for(x=i; i<HDRSIZ; i++,j++)
113: p[j] = p[i];
114:
115: q1.c_cc = -x;
116: q1.c_cf = (caddr_t)((int)p + j);
117: goto istart2;
118: }
119: if (x == pk->p_rsize) {
120: pkdata(h->cntl, h->sum, pk, q1.c_cl);
121: pk->p_io = NULL;
122: q1.c_cf = (char *)h;
123: q1.c_cc = -HDRSIZ;
124: goto istart1;
125: }
126: if (x == 0) {
127: q1.c_cf = (char *)h;
128: q1.c_cc = -HDRSIZ;
129: pkbadframe(pk);
130: } else {
131: pkbadframe(pk);
132: goto scan;
133: }
134: istart1:
135: q1.c_cl = q1.c_cf;
136: istart2:
137: if (tp->t_iproc != NULL)
138: (*tp->t_iproc)(tp);
139: }
140:
141:
142:
143: /*
144: * Put packet located at address bp
145: * in an input slot for further processing.
146: */
147: pkdata(c, sum, pk, cp)
148: char c;
149: unsigned short sum;
150: register struct pack *pk;
151: char *cp;
152: {
153: register struct tty *tp;
154: register x;
155: char **bp;
156: int t;
157:
158: pk->p_state &= ~BADFRAME;
159: bp = (char **)cp;
160: tp = pk->p_ttyp;
161: if (pk->p_state&DRAINO || !(pk->p_state&LIVE)) {
162: pk->p_msg |= pk->p_rmsg;
163: pkoutput(pk);
164: goto drop;
165: }
166: t = next[pk->p_pr];
167: for(x=pk->p_pr; x!=t; x = (x-1)&7) {
168: if (pk->p_is[x] == 0)
169: goto slot;
170: }
171: /*
172: * this can't happen
173: */
174: printf("no slot\n");
175: drop:
176: *bp = (char *)pk->p_ipool;
177: pk->p_ipool = bp;
178: return;
179:
180: slot:
181: pk->p_imap |= mask[x];
182: pk->p_is[x] = c;
183: pk->p_isum[x] = sum;
184: pk->p_ib[x] = cp;
185: if (tp->t_chan)
186: sdata(tp->t_chan); else
187: wakeup(&pk->p_pr);
188: }
189:
190:
191: /*
192: * Start transmission on output device associated with pk.
193: * For asynch devices (t_line==1) framing is
194: * imposed. For devices with framing and crc
195: * in the driver (t_line==2) the transfer is
196: * passed on to the driver.
197: */
198: pkxstart(pk, cntl, x)
199: struct pack *pk;
200: char cntl;
201: register x;
202: {
203: struct tty *tp;
204: register char *p;
205: short checkword;
206: char hdcheck;
207:
208: p = (caddr_t)&pk->p_ohbuf;
209: tp = pk->p_ttyp;
210:
211: if (tp->t_line==1) {
212: *p++ = SYN;
213: if (x < 0) {
214: *p = 9;
215: checkword = cntl;
216: q3.c_cl = NULL;
217: } else {
218: *p = pk->p_lpsize;
219: checkword = pk->p_osum[x] ^ (unsigned)cntl;
220: q3.c_cl = pk->p_ob[x];
221: }
222: checkword = CHECK - checkword;
223: hdcheck = *p++;
224: hdcheck ^= *p++ = checkword;
225: hdcheck ^= *p++ = checkword>>8;
226: q3.c_cc = -HDRSIZ;
227: } else {
228: q3.c_cc = -1;
229: }
230:
231: hdcheck ^= *p++ = cntl;
232: *p = hdcheck;
233: q3.c_cf = (caddr_t)&pk->p_ohbuf;
234: /*
235: pk->p_srxmit++;
236: */
237: (*tp->t_oproc)(tp);
238: }
239:
240: /*
241: * transmitter interrupt.
242: */
243: int pkdelay = 2;
244:
245: pkxint(tp)
246: register struct tty *tp;
247: {
248: register struct pack *pk;
249: register s;
250: extern int pkoutput();
251:
252: pk = (struct pack *)tp->t_linep;
253: s = spl6();
254: tp->t_state &= ~BUSY;
255: if (q3.c_cl == NULL) {
256: pkoutput(pk);
257: } else {
258: q3.c_cf = q3.c_cl;
259: q3.c_cl = NULL;
260: q3.c_cc = -pk->p_xsize;
261: (*tp->t_oproc)(tp);
262: }
263: splx(s);
264: }
Defined functions
Defined variables
Defined macros
KERNEL
defined in line
1;
never used