very high watermarks for 19.2 and 38.4k baud
[unix-history] / usr / src / sys / kern / tty_subr.c
CommitLineData
a42d8a6b 1/* tty_subr.c 4.15 82/03/14 */
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
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
a42d8a6b 57#if notdef
11bd398c
BJ
58/*
59 * copy clist to buffer.
60 * return number of bytes moved.
61 */
62q_to_b(q, cp, cc)
63register struct clist *q;
64register char *cp;
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}
2752c877 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)
121register struct clist *q;
122{
123register cc;
124int s;
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)
161register struct clist *q;
162register cc;
163{
48575cec
BJ
164register struct cblock *bp;
165char *end;
166int rem;
11bd398c
BJ
167register s;
168
7eb2e67e 169 s = spl5();
11bd398c 170 if (q->c_cc < 0) {
48575cec 171 printf("neg q flush\n");
11bd398c
BJ
172 goto out;
173 }
174 if (q->c_cc == 0) {
175 goto out;
176 }
48575cec
BJ
177 while (cc>0 && q->c_cc) {
178 bp = (struct cblock *)((int)q->c_cf & ~CROUND);
179 if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
180 end = q->c_cl;
181 } else {
182 end = (char *)((int)bp + sizeof (struct cblock));
183 }
184 rem = end - q->c_cf;
185 if (cc >= rem) {
186 cc -= rem;
187 q->c_cc -= rem;
11bd398c 188 q->c_cf = bp->c_next->c_info;
48575cec
BJ
189 bp->c_next = cfreelist;
190 cfreelist = bp;
191 cfreecount += CBSIZE;
192 if (cwaiting) {
193 wakeup(&cwaiting);
194 cwaiting = 0;
195 }
11bd398c 196 } else {
48575cec
BJ
197 q->c_cc -= cc;
198 q->c_cf += cc;
199 if (q->c_cc <= 0) {
200 bp->c_next = cfreelist;
201 cfreelist = bp;
202 cfreecount += CBSIZE;
203 if (cwaiting) {
204 wakeup(&cwaiting);
205 cwaiting = 0;
206 }
207 }
208 break;
11bd398c 209 }
48575cec
BJ
210 }
211 if (q->c_cc <= 0) {
11bd398c 212 q->c_cf = q->c_cl = NULL;
48575cec 213 q->c_cc = 0;
11bd398c
BJ
214 }
215out:
216 splx(s);
217}
b8f09f36 218
48575cec 219
11bd398c
BJ
220putc(c, p)
221register struct clist *p;
222{
223 register struct cblock *bp;
224 register char *cp;
225 register s;
226
7eb2e67e 227 s = spl5();
11bd398c
BJ
228 if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
229 if ((bp = cfreelist) == NULL) {
230 splx(s);
231 return(-1);
232 }
233 cfreelist = bp->c_next;
48575cec 234 cfreecount -= CBSIZE;
11bd398c
BJ
235 bp->c_next = NULL;
236 p->c_cf = cp = bp->c_info;
237 } else if (((int)cp & CROUND) == 0) {
238 bp = (struct cblock *)cp - 1;
239 if ((bp->c_next = cfreelist) == NULL) {
240 splx(s);
241 return(-1);
242 }
243 bp = bp->c_next;
244 cfreelist = bp->c_next;
48575cec 245 cfreecount -= CBSIZE;
11bd398c
BJ
246 bp->c_next = NULL;
247 cp = bp->c_info;
248 }
249 *cp++ = c;
250 p->c_cc++;
251 p->c_cl = cp;
252 splx(s);
253 return(0);
254}
255
48575cec
BJ
256
257
11bd398c
BJ
258/*
259 * copy buffer to clist.
260 * return number of bytes not transfered.
261 */
262b_to_q(cp, cc, q)
263register char *cp;
264struct clist *q;
265register int cc;
266{
267 register char *cq;
268 register struct cblock *bp;
269 register s, acc;
270
271 if (cc <= 0)
272 return(0);
273 acc = cc;
48575cec
BJ
274
275
7eb2e67e 276 s = spl5();
11bd398c
BJ
277 if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
278 if ((bp = cfreelist) == NULL)
279 goto out;
280 cfreelist = bp->c_next;
48575cec 281 cfreecount -= CBSIZE;
11bd398c
BJ
282 bp->c_next = NULL;
283 q->c_cf = cq = bp->c_info;
284 }
285
286 while (cc) {
287 if (((int)cq & CROUND) == 0) {
288 bp = (struct cblock *) cq - 1;
289 if ((bp->c_next = cfreelist) == NULL)
290 goto out;
291 bp = bp->c_next;
292 cfreelist = bp->c_next;
48575cec 293 cfreecount -= CBSIZE;
11bd398c
BJ
294 bp->c_next = NULL;
295 cq = bp->c_info;
296 }
297 *cq++ = *cp++;
298 cc--;
299 }
300out:
301 q->c_cl = cq;
302 q->c_cc += acc-cc;
303 splx(s);
304 return(cc);
305}
306
b8f09f36
BJ
307/*
308 * Given a non-NULL pointter into the list (like c_cf which
309 * always points to a real character if non-NULL) return the pointer
310 * to the next character in the list or return NULL if no more chars.
311 *
312 * Callers must not allow getc's to happen between nextc's so that the
313 * pointer becomes invalid. Note that interrupts are NOT masked.
314 */
315char *
316nextc(p, cp)
317register struct clist *p;
318register char *cp;
319{
320
321 if (p->c_cc && ++cp != p->c_cl) {
322 if (((int)cp & CROUND) == 0)
323 return (((struct cblock *)cp)[-1].c_next->c_info);
324 return (cp);
325 }
326 return (0);
327}
328
329/*
330 * Remove the last character in the list and return it.
331 */
332unputc(p)
333register struct clist *p;
334{
335 register struct cblock *bp;
336 register int c, s;
337 struct cblock *obp;
338
7eb2e67e 339 s = spl5();
b8f09f36
BJ
340 if (p->c_cc <= 0)
341 c = -1;
342 else {
343 c = *--p->c_cl;
344 if (--p->c_cc <= 0) {
345 bp = (struct cblock *)p->c_cl;
346 bp = (struct cblock *)((int)bp & ~CROUND);
347 p->c_cl = p->c_cf = NULL;
348 bp->c_next = cfreelist;
349 cfreelist = bp;
48575cec 350 cfreecount += CBSIZE;
b8f09f36
BJ
351 } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) {
352 p->c_cl = (char *)((int)p->c_cl & ~CROUND);
353 bp = (struct cblock *)p->c_cf;
354 bp = (struct cblock *)((int)bp & ~CROUND);
355 while (bp->c_next != (struct cblock *)p->c_cl)
356 bp = bp->c_next;
357 obp = bp;
358 p->c_cl = (char *)(bp + 1);
359 bp = bp->c_next;
360 bp->c_next = cfreelist;
361 cfreelist = bp;
48575cec 362 cfreecount += CBSIZE;
b8f09f36
BJ
363 obp->c_next = NULL;
364 }
365 }
366 splx(s);
367 return (c);
368}
369
370/*
371 * Put the chars in the from que
372 * on the end of the to que.
373 *
374 * SHOULD JUST USE q_to_b AND THEN b_to_q HERE.
375 */
376catq(from, to)
377struct clist *from, *to;
378{
379 register c;
380
381 while ((c = getc(from)) >= 0)
382 (void) putc(c, to);
383}
384
cc04de27
BJ
385#include "dmc.h"
386#if NDMC > 0
11bd398c
BJ
387/*
388 * integer (2-byte) get/put
389 * using clists
390 */
11bd398c
BJ
391getw(p)
392register struct clist *p;
393{
394 register int s;
395
396 if (p->c_cc <= 1)
397 return(-1);
398 s = getc(p);
399 return(s | (getc(p)<<8));
400}
48575cec 401
11bd398c
BJ
402putw(c, p)
403register struct clist *p;
404{
405 register s;
406
7eb2e67e 407 s = spl5();
11bd398c
BJ
408 if (cfreelist==NULL) {
409 splx(s);
410 return(-1);
411 }
81263dba
BJ
412 (void) putc(c, p);
413 (void) putc(c>>8, p);
11bd398c
BJ
414 splx(s);
415 return(0);
416}
2752c877 417#endif