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