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