fixups just pre lint
[unix-history] / usr / src / sys / kern / tty_subr.c
CommitLineData
0e8a6d93 1/* tty_subr.c 4.8 %G% */
8f6119af 2
11bd398c 3#include "../h/param.h"
11bd398c
BJ
4#include "../h/systm.h"
5#include "../h/conf.h"
6#include "../h/buf.h"
48575cec 7#include "../h/tty.h"
d4df41fe 8#include "../h/clist.h"
11bd398c 9
48575cec 10char cwaiting;
11bd398c
BJ
11
12/*
13 * Character list get/put
14 */
15getc(p)
16register struct clist *p;
17{
18 register struct cblock *bp;
19 register int c, s;
20
21 s = spl6();
22 if (p->c_cc <= 0) {
23 c = -1;
24 p->c_cc = 0;
25 p->c_cf = p->c_cl = NULL;
26 } else {
27 c = *p->c_cf++ & 0377;
28 if (--p->c_cc<=0) {
29 bp = (struct cblock *)(p->c_cf-1);
30 bp = (struct cblock *) ((int)bp & ~CROUND);
31 p->c_cf = NULL;
32 p->c_cl = NULL;
33 bp->c_next = cfreelist;
34 cfreelist = bp;
48575cec
BJ
35 cfreecount += CBSIZE;
36 if (cwaiting) {
37 wakeup(&cwaiting);
38 cwaiting = 0;
39 }
11bd398c
BJ
40 } else if (((int)p->c_cf & CROUND) == 0){
41 bp = (struct cblock *)(p->c_cf);
42 bp--;
43 p->c_cf = bp->c_next->c_info;
44 bp->c_next = cfreelist;
45 cfreelist = bp;
48575cec
BJ
46 cfreecount += CBSIZE;
47 if (cwaiting) {
48 wakeup(&cwaiting);
49 cwaiting = 0;
50 }
11bd398c
BJ
51 }
52 }
53 splx(s);
54 return(c);
55}
56
57/*
58 * copy clist to buffer.
59 * return number of bytes moved.
60 */
61q_to_b(q, cp, cc)
62register struct clist *q;
63register char *cp;
64{
65 register struct cblock *bp;
66 register int s;
67 char *acp;
68
69 if (cc <= 0)
70 return(0);
71 s = spl6();
72 if (q->c_cc <= 0) {
73 q->c_cc = 0;
74 q->c_cf = q->c_cl = NULL;
48575cec 75 splx(s);
11bd398c
BJ
76 return(0);
77 }
78 acp = cp;
79 cc++;
80
81 while (--cc) {
82 *cp++ = *q->c_cf++;
83 if (--q->c_cc <= 0) {
84 bp = (struct cblock *)(q->c_cf-1);
85 bp = (struct cblock *)((int)bp & ~CROUND);
86 q->c_cf = q->c_cl = NULL;
87 bp->c_next = cfreelist;
88 cfreelist = bp;
48575cec
BJ
89 cfreecount += CBSIZE;
90 if (cwaiting) {
91 wakeup(&cwaiting);
92 cwaiting = 0;
93 }
11bd398c
BJ
94 break;
95 }
96 if (((int)q->c_cf & CROUND) == 0) {
97 bp = (struct cblock *)(q->c_cf);
98 bp--;
99 q->c_cf = bp->c_next->c_info;
100 bp->c_next = cfreelist;
101 cfreelist = bp;
48575cec
BJ
102 cfreecount += CBSIZE;
103 if (cwaiting) {
104 wakeup(&cwaiting);
105 cwaiting = 0;
106 }
11bd398c
BJ
107 }
108 }
109 splx(s);
110 return(cp-acp);
111}
112
11bd398c
BJ
113/*
114 * Return count of contiguous characters
115 * in clist starting at q->c_cf.
116 * Stop counting if flag&character is non-null.
117 */
118ndqb(q, flag)
119register struct clist *q;
120{
121register cc;
122int s;
123
124 s = spl6();
125 if (q->c_cc <= 0) {
126 cc = -q->c_cc;
127 goto out;
128 }
129 cc = ((int)q->c_cf + CBSIZE) & ~CROUND;
130 cc -= (int)q->c_cf;
131 if (q->c_cc < cc)
132 cc = q->c_cc;
133 if (flag) {
134 register char *p, *end;
135
136 p = q->c_cf;
137 end = p;
138 end += cc;
139 while (p < end) {
140 if (*p & flag) {
48575cec
BJ
141 cc = (int)p;
142 cc -= (int)q->c_cf;
11bd398c
BJ
143 break;
144 }
145 p++;
146 }
147 }
148out:
149 splx(s);
150 return(cc);
151}
152
48575cec
BJ
153
154
11bd398c 155/*
48575cec 156 * Flush cc bytes from q.
11bd398c
BJ
157 */
158ndflush(q, cc)
159register struct clist *q;
160register cc;
161{
48575cec
BJ
162register struct cblock *bp;
163char *end;
164int rem;
11bd398c
BJ
165register s;
166
11bd398c
BJ
167 s = spl6();
168 if (q->c_cc < 0) {
48575cec 169 printf("neg q flush\n");
11bd398c
BJ
170 goto out;
171 }
172 if (q->c_cc == 0) {
173 goto out;
174 }
48575cec
BJ
175 while (cc>0 && q->c_cc) {
176 bp = (struct cblock *)((int)q->c_cf & ~CROUND);
177 if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
178 end = q->c_cl;
179 } else {
180 end = (char *)((int)bp + sizeof (struct cblock));
181 }
182 rem = end - q->c_cf;
183 if (cc >= rem) {
184 cc -= rem;
185 q->c_cc -= rem;
11bd398c 186 q->c_cf = bp->c_next->c_info;
48575cec
BJ
187 bp->c_next = cfreelist;
188 cfreelist = bp;
189 cfreecount += CBSIZE;
190 if (cwaiting) {
191 wakeup(&cwaiting);
192 cwaiting = 0;
193 }
11bd398c 194 } else {
48575cec
BJ
195 q->c_cc -= cc;
196 q->c_cf += cc;
197 if (q->c_cc <= 0) {
198 bp->c_next = cfreelist;
199 cfreelist = bp;
200 cfreecount += CBSIZE;
201 if (cwaiting) {
202 wakeup(&cwaiting);
203 cwaiting = 0;
204 }
205 }
206 break;
11bd398c 207 }
48575cec
BJ
208 }
209 if (q->c_cc <= 0) {
11bd398c 210 q->c_cf = q->c_cl = NULL;
48575cec 211 q->c_cc = 0;
11bd398c
BJ
212 }
213out:
214 splx(s);
215}
b8f09f36 216
48575cec 217
11bd398c
BJ
218putc(c, p)
219register struct clist *p;
220{
221 register struct cblock *bp;
222 register char *cp;
223 register s;
224
225 s = spl6();
226 if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
227 if ((bp = cfreelist) == NULL) {
228 splx(s);
229 return(-1);
230 }
231 cfreelist = bp->c_next;
48575cec 232 cfreecount -= CBSIZE;
11bd398c
BJ
233 bp->c_next = NULL;
234 p->c_cf = cp = bp->c_info;
235 } else if (((int)cp & CROUND) == 0) {
236 bp = (struct cblock *)cp - 1;
237 if ((bp->c_next = cfreelist) == NULL) {
238 splx(s);
239 return(-1);
240 }
241 bp = bp->c_next;
242 cfreelist = bp->c_next;
48575cec 243 cfreecount -= CBSIZE;
11bd398c
BJ
244 bp->c_next = NULL;
245 cp = bp->c_info;
246 }
247 *cp++ = c;
248 p->c_cc++;
249 p->c_cl = cp;
250 splx(s);
251 return(0);
252}
253
48575cec
BJ
254
255
11bd398c
BJ
256/*
257 * copy buffer to clist.
258 * return number of bytes not transfered.
259 */
260b_to_q(cp, cc, q)
261register char *cp;
262struct clist *q;
263register int cc;
264{
265 register char *cq;
266 register struct cblock *bp;
267 register s, acc;
268
269 if (cc <= 0)
270 return(0);
271 acc = cc;
48575cec
BJ
272
273
11bd398c
BJ
274 s = spl6();
275 if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
276 if ((bp = cfreelist) == NULL)
277 goto out;
278 cfreelist = bp->c_next;
48575cec 279 cfreecount -= CBSIZE;
11bd398c
BJ
280 bp->c_next = NULL;
281 q->c_cf = cq = bp->c_info;
282 }
283
284 while (cc) {
285 if (((int)cq & CROUND) == 0) {
286 bp = (struct cblock *) cq - 1;
287 if ((bp->c_next = cfreelist) == NULL)
288 goto out;
289 bp = bp->c_next;
290 cfreelist = bp->c_next;
48575cec 291 cfreecount -= CBSIZE;
11bd398c
BJ
292 bp->c_next = NULL;
293 cq = bp->c_info;
294 }
295 *cq++ = *cp++;
296 cc--;
297 }
298out:
299 q->c_cl = cq;
300 q->c_cc += acc-cc;
301 splx(s);
302 return(cc);
303}
304
48575cec
BJ
305char *
306wb_to_q(cp, cc, q)
307register char *cp;
308register struct clist *q;
309register cc;
310{
311char *f;
312register s;
313
314 s = spl6();
315 while (cc > cfreecount) {
316 cwaiting = 1;
317 sleep(&cwaiting, TTOPRI);
318 }
319 if (q->c_cc==0) {
320 b_to_q(cp, cc, q);
321 f = q->c_cf;
322 } else {
323 (void) putc(*cp++, q);
324 f = q->c_cl;
325 f--;
326 b_to_q(cp, --cc, q);
327 }
328 splx(s);
329 return(f);
330}
331
b8f09f36
BJ
332/*
333 * Given a non-NULL pointter into the list (like c_cf which
334 * always points to a real character if non-NULL) return the pointer
335 * to the next character in the list or return NULL if no more chars.
336 *
337 * Callers must not allow getc's to happen between nextc's so that the
338 * pointer becomes invalid. Note that interrupts are NOT masked.
339 */
340char *
341nextc(p, cp)
342register struct clist *p;
343register char *cp;
344{
345
346 if (p->c_cc && ++cp != p->c_cl) {
347 if (((int)cp & CROUND) == 0)
348 return (((struct cblock *)cp)[-1].c_next->c_info);
349 return (cp);
350 }
351 return (0);
352}
353
354/*
355 * Remove the last character in the list and return it.
356 */
357unputc(p)
358register struct clist *p;
359{
360 register struct cblock *bp;
361 register int c, s;
362 struct cblock *obp;
363
364 s = spl6();
365 if (p->c_cc <= 0)
366 c = -1;
367 else {
368 c = *--p->c_cl;
369 if (--p->c_cc <= 0) {
370 bp = (struct cblock *)p->c_cl;
371 bp = (struct cblock *)((int)bp & ~CROUND);
372 p->c_cl = p->c_cf = NULL;
373 bp->c_next = cfreelist;
374 cfreelist = bp;
48575cec 375 cfreecount += CBSIZE;
b8f09f36
BJ
376 } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) {
377 p->c_cl = (char *)((int)p->c_cl & ~CROUND);
378 bp = (struct cblock *)p->c_cf;
379 bp = (struct cblock *)((int)bp & ~CROUND);
380 while (bp->c_next != (struct cblock *)p->c_cl)
381 bp = bp->c_next;
382 obp = bp;
383 p->c_cl = (char *)(bp + 1);
384 bp = bp->c_next;
385 bp->c_next = cfreelist;
386 cfreelist = bp;
48575cec 387 cfreecount += CBSIZE;
b8f09f36
BJ
388 obp->c_next = NULL;
389 }
390 }
391 splx(s);
392 return (c);
393}
394
395/*
396 * Put the chars in the from que
397 * on the end of the to que.
398 *
399 * SHOULD JUST USE q_to_b AND THEN b_to_q HERE.
400 */
401catq(from, to)
402struct clist *from, *to;
403{
404 register c;
405
406 while ((c = getc(from)) >= 0)
407 (void) putc(c, to);
408}
409
11bd398c
BJ
410/*
411 * integer (2-byte) get/put
412 * using clists
413 */
11bd398c
BJ
414getw(p)
415register struct clist *p;
416{
417 register int s;
418
419 if (p->c_cc <= 1)
420 return(-1);
421 s = getc(p);
422 return(s | (getc(p)<<8));
423}
48575cec 424
11bd398c
BJ
425putw(c, p)
426register struct clist *p;
427{
428 register s;
429
430 s = spl6();
431 if (cfreelist==NULL) {
432 splx(s);
433 return(-1);
434 }
81263dba
BJ
435 (void) putc(c, p);
436 (void) putc(c>>8, p);
11bd398c
BJ
437 splx(s);
438 return(0);
439}