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