1: #define KERNEL 1
2: #include <sys/pk.p>
3:
4: #ifdef UCB_SCCSID
5: static char sccs_id[] = "@(#)pk1.c 3.1";
6: #endif
7:
8:
9:
10: /*
11: * kernel support routines.
12: */
13:
14: struct pack *pklines[NPLINES];
15: int maxwindow =2;
16:
17: /*
18: * start initial synchronization.
19: * allocate space.
20: */
21: pkopen(dev, tp, addr)
22: register struct tty *tp;
23: caddr_t addr;
24: {
25: register struct pack *pk;
26: register i;
27: int pktimeout();
28: char **bp;
29: static timer_on;
30: int s;
31: struct piocb piocb;
32:
33:
34: if (tp->t_line)
35: return;
36: /*
37: * copy user parameters
38: */
39: if (copyin(addr, (caddr_t)&piocb, sizeof (piocb))) {
40: u.u_error = EFAULT;
41: return;
42: }
43: npbits = dtom(sizeof(struct pack));
44: pk = (struct pack *)getepack(npbits);
45: if (pk==NULL)
46: goto notsobad;
47: pkzero((caddr_t)pk,sizeof (struct pack));
48: pk->p_rwindow = piocb.window;
49: if (pk->p_rwindow > maxwindow)
50: pk->p_rwindow = maxwindow;
51: pk->p_rsize = piocb.psize;
52: if (pk->p_rsize > 512 || pk->p_rsize & 037)
53: goto notsobad;
54: pk->p_mode = piocb.mode;
55: if (pk->p_mode & 01)
56: pkdebug++;
57: /*
58: * try to allocate input window
59: */
60: pk->p_bits = dtom(pk->p_rsize);
61: for(i=0; i<pk->p_rwindow; i++) {
62: bp = (char **)getepack(pk->p_bits);
63: if (bp==NULL)
64: break;
65: *bp = (char *)pk->p_ipool;
66: pk->p_ipool = bp;
67: }
68:
69: if (i==0 && bp==NULL)
70: goto notsobad;
71: pk->p_rwindow = i;
72:
73:
74: /*
75: * start timer process,
76: * wait for synchronization.
77: */
78: flushtty(tp);
79: s = spl6();
80: pkdisc = tp->t_line = piocb.t;
81: pk->p_ttyp = tp;
82: tp->t_linep = (caddr_t)pk;
83: q2.c_cf = q2.c_cl = NULL;
84: q1.c_cf = q1.c_cl = (caddr_t)&pk->p_ihbuf;
85: q1.c_cc = -HDRSIZ;
86: if (tp->t_iproc != NULL)
87: (*tp->t_iproc)(tp);
88:
89: pk->p_rmsg = M_INITA;
90: for(i=0; i<NPLINES; i++) {
91: if (pklines[i]==NULL) {
92: pklines[i] = pk;
93: goto found;
94: }
95: }
96: goto notsobad;
97: found:
98: pk->p_timer++;
99: if (timer_on==0) {
100: timer_on++;
101: pktimeout();
102: }
103: splx(s);
104: SLEEP(&pk->p_state, PKOPRI);
105: pkreset(pk);
106:
107: if ((pk->p_state&LIVE)==0) {
108: pk->p_state = DOWN;
109: pk->p_rmsg = 0;
110: notsobad:
111: u.u_error = ENXIO;
112: return;
113: }
114:
115: pksetgrp(tp);
116: pkioctl(DIOCGETP, tp, addr);
117:
118: }
119:
120:
121:
122:
123: /*
124: * unix ioctl interface
125: */
126: pkioctl(com,tp,addr)
127: register struct tty *tp;
128: caddr_t addr;
129: {
130: struct piocb piocb;
131: register struct pack *pk;
132:
133: pk = (struct pack *)tp->t_linep;
134: if (com == DIOCGETP) {
135: piocb.window = pk->p_swindow;
136: piocb.psize = pk->p_xsize;
137: piocb.state = pk->p_state;
138: if (copyout((caddr_t)&piocb, addr, sizeof(piocb))) {
139: u.u_error = EFAULT;
140: }
141: if (u.u_error==0)
142: u.u_r.r_val1 = piocb.psize;
143: }
144: }
145:
146:
147: /*
148: * Arrange for the device (i.e. tp)
149: * to be able to generate signals if need be.
150: */
151: pksetgrp(tp)
152: register struct tty *tp;
153: {
154: register struct proc *pp;
155:
156: pp = u.u_procp;
157: if (pp->p_pgrp == 0)
158: pp->p_pgrp = pp->p_pid;
159: if (tp->t_pgrp == 0)
160: tp->t_pgrp = pp->p_pgrp;
161: }
162:
163:
164:
165: /*
166: * Shut down io.
167: * The problem is mainly input since the
168: * device driver may have a buffer.
169: */
170: pkturnoff(tp)
171: register struct tty *tp;
172: {
173: register char **bp;
174: register struct pack *pk;
175: register s;
176:
177: pk = PADDR;
178: LOCK;
179: bp = pk->p_io;
180: tp->t_line = 0;
181: q1.c_cf = NULL;
182: flushtty(tp);
183: if (bp!=NULL) {
184: *bp = (char *)pk->p_ipool;
185: pk->p_ipool = bp;
186: }
187: UNLOCK;
188: }
189:
190:
191:
192: /*
193: * link dead?
194: */
195: pklive(pk)
196: register struct pack *pk;
197: {
198: register struct tty *tp;
199:
200: tp = pk->p_ttyp;
201: if (tp->t_line!=pkdisc || tp->t_linep!=(caddr_t)pk) {
202: return(0);
203: }
204: return(tp->t_state&CARR_ON);
205: }
206:
207:
208:
209: /*
210: * timeout process:
211: * wakes up periodically to check status
212: * of active lines.
213: */
214: pktimeout()
215: {
216: register struct pack *pk;
217: extern time_t time;
218: register i;
219:
220: for(i=0;i<NPLINES;i++) {
221: if ((pk=pklines[i])==NULL)
222: continue;
223: if (pk->p_nout == pk->p_tout) {
224: if (pk->p_xcount && pk->p_timer==0) {
225: pk->p_timer = 3;
226: pk->p_state |= WAITO;
227: }
228: } else
229: pk->p_tout = pk->p_nout;
230: if (pk->p_timer==0) {
231: if (pk->p_state & BADFRAME) {
232: pk->p_msg |= M_RJ;
233: pk->p_state &= ~BADFRAME;
234: goto startup;
235: }
236: if (pk->p_rmsg)
237: goto startup;
238: WAKEUP(&pk->p_ps);
239: continue;
240: }
241: if (--pk->p_timer == 0) {
242: if ((pk->p_state&LIVE)==0) {
243: startup:
244: pk->p_timer = 1;
245: } else
246: if (pk->p_state & WAITO) {
247: if (pk->p_state&DRAINO) {
248: pk->p_state |= DOWN;
249: } else {
250: pk->p_state |= RXMIT;
251: }
252: pkoutput(pk);
253: pk->p_timer = 5+2*pkzot;
254: }
255: WAKEUP(&pk->p_ps);
256: pk->p_msg |= pk->p_rmsg;
257: if (pk->p_msg)
258: pkoutput(pk);
259: }
260: }
261: timeout(pktimeout, (caddr_t)pk, 60);
262:
263:
264: /*
265: * randomize timeouts.
266: */
267: pkzot = 2 + time&07;
268: }
Defined functions
Defined variables
Defined macros
KERNEL
defined in line
1;
never used