1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)tty_subr.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: #include "param.h"
10: #include "systm.h"
11: #include "buf.h"
12: #include "ioctl.h"
13: #include "tty.h"
14: #include "clist.h"
15:
16: char cwaiting;
17:
18: /*
19: * Character list get/put
20: */
21: getc(p)
22: register struct clist *p;
23: {
24: register struct cblock *bp;
25: register int c, s;
26:
27: s = spltty();
28: if (p->c_cc <= 0) {
29: c = -1;
30: p->c_cc = 0;
31: p->c_cf = p->c_cl = NULL;
32: } else {
33: c = *p->c_cf++ & 0377;
34: if (--p->c_cc<=0) {
35: bp = (struct cblock *)(p->c_cf-1);
36: bp = (struct cblock *)((int)bp & ~CROUND);
37: p->c_cf = NULL;
38: p->c_cl = NULL;
39: bp->c_next = cfreelist;
40: cfreelist = bp;
41: cfreecount += CBSIZE;
42: if (cwaiting) {
43: wakeup(&cwaiting);
44: cwaiting = 0;
45: }
46: } else if (((int)p->c_cf & CROUND) == 0){
47: bp = (struct cblock *)(p->c_cf);
48: bp--;
49: p->c_cf = bp->c_next->c_info;
50: bp->c_next = cfreelist;
51: cfreelist = bp;
52: cfreecount += CBSIZE;
53: if (cwaiting) {
54: wakeup(&cwaiting);
55: cwaiting = 0;
56: }
57: }
58: }
59: splx(s);
60: return (c);
61: }
62:
63: /*
64: * copy clist to buffer.
65: * return number of bytes moved.
66: */
67: q_to_b(q, cp, cc)
68: register struct clist *q;
69: register char *cp;
70: {
71: register struct cblock *bp;
72: register int s;
73: register nc;
74: char *acp;
75:
76: if (cc <= 0)
77: return (0);
78: s = spltty();
79: if (q->c_cc <= 0) {
80: q->c_cc = 0;
81: q->c_cf = q->c_cl = NULL;
82: splx(s);
83: return (0);
84: }
85: acp = cp;
86:
87: while (cc) {
88: nc = sizeof (struct cblock) - ((int)q->c_cf & CROUND);
89: nc = MIN(nc, cc);
90: nc = MIN(nc, q->c_cc);
91: (void) bcopy(q->c_cf, cp, (unsigned)nc);
92: q->c_cf += nc;
93: q->c_cc -= nc;
94: cc -= nc;
95: cp += nc;
96: if (q->c_cc <= 0) {
97: bp = (struct cblock *)(q->c_cf - 1);
98: bp = (struct cblock *)((int)bp & ~CROUND);
99: q->c_cf = q->c_cl = NULL;
100: bp->c_next = cfreelist;
101: cfreelist = bp;
102: cfreecount += CBSIZE;
103: if (cwaiting) {
104: wakeup(&cwaiting);
105: cwaiting = 0;
106: }
107: break;
108: }
109: if (((int)q->c_cf & CROUND) == 0) {
110: bp = (struct cblock *)(q->c_cf);
111: bp--;
112: q->c_cf = bp->c_next->c_info;
113: bp->c_next = cfreelist;
114: cfreelist = bp;
115: cfreecount += CBSIZE;
116: if (cwaiting) {
117: wakeup(&cwaiting);
118: cwaiting = 0;
119: }
120: }
121: }
122: splx(s);
123: return (cp-acp);
124: }
125:
126: /*
127: * Return count of contiguous characters
128: * in clist starting at q->c_cf.
129: * Stop counting if flag&character is non-null.
130: */
131: ndqb(q, flag)
132: register struct clist *q;
133: {
134: register cc;
135: int s;
136:
137: s = spltty();
138: if (q->c_cc <= 0) {
139: cc = -q->c_cc;
140: goto out;
141: }
142: cc = ((int)q->c_cf + CBSIZE) & ~CROUND;
143: cc -= (int)q->c_cf;
144: if (q->c_cc < cc)
145: cc = q->c_cc;
146: if (flag) {
147: register char *p, *end;
148:
149: p = q->c_cf;
150: end = p;
151: end += cc;
152: while (p < end) {
153: if (*p & flag) {
154: cc = (int)p;
155: cc -= (int)q->c_cf;
156: break;
157: }
158: p++;
159: }
160: }
161: out:
162: splx(s);
163: return (cc);
164: }
165:
166: /*
167: * Flush cc bytes from q.
168: */
169: ndflush(q, cc)
170: register struct clist *q;
171: register cc;
172: {
173: register struct cblock *bp;
174: char *end;
175: int rem, s;
176:
177: s = spltty();
178: if (q->c_cc <= 0)
179: goto out;
180: while (cc>0 && q->c_cc) {
181: bp = (struct cblock *)((int)q->c_cf & ~CROUND);
182: if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
183: end = q->c_cl;
184: } else {
185: end = (char *)((int)bp + sizeof (struct cblock));
186: }
187: rem = end - q->c_cf;
188: if (cc >= rem) {
189: cc -= rem;
190: q->c_cc -= rem;
191: q->c_cf = bp->c_next->c_info;
192: bp->c_next = cfreelist;
193: cfreelist = bp;
194: cfreecount += CBSIZE;
195: if (cwaiting) {
196: wakeup(&cwaiting);
197: cwaiting = 0;
198: }
199: } else {
200: q->c_cc -= cc;
201: q->c_cf += cc;
202: if (q->c_cc <= 0) {
203: bp->c_next = cfreelist;
204: cfreelist = bp;
205: cfreecount += CBSIZE;
206: if (cwaiting) {
207: wakeup(&cwaiting);
208: cwaiting = 0;
209: }
210: }
211: break;
212: }
213: }
214: if (q->c_cc <= 0) {
215: q->c_cf = q->c_cl = NULL;
216: q->c_cc = 0;
217: }
218: out:
219: splx(s);
220: }
221:
222:
223: putc(c, p)
224: register struct clist *p;
225: {
226: register struct cblock *bp;
227: register char *cp;
228: register s;
229:
230: s = spltty();
231: if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
232: if ((bp = cfreelist) == NULL) {
233: splx(s);
234: return (-1);
235: }
236: cfreelist = bp->c_next;
237: cfreecount -= CBSIZE;
238: bp->c_next = NULL;
239: p->c_cf = cp = bp->c_info;
240: } else if (((int)cp & CROUND) == 0) {
241: bp = (struct cblock *)cp - 1;
242: if ((bp->c_next = cfreelist) == NULL) {
243: splx(s);
244: return (-1);
245: }
246: bp = bp->c_next;
247: cfreelist = bp->c_next;
248: cfreecount -= CBSIZE;
249: bp->c_next = NULL;
250: cp = bp->c_info;
251: }
252: *cp++ = c;
253: p->c_cc++;
254: p->c_cl = cp;
255: splx(s);
256: return (0);
257: }
258:
259: /*
260: * copy buffer to clist.
261: * return number of bytes not transfered.
262: */
263: b_to_q(cp, cc, q)
264: register char *cp;
265: struct clist *q;
266: register int cc;
267: {
268: register char *cq;
269: register struct cblock *bp;
270: register s, nc;
271: int acc;
272:
273: if (cc <= 0)
274: return (0);
275: acc = cc;
276: s = spltty();
277: if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
278: if ((bp = cfreelist) == NULL)
279: goto out;
280: cfreelist = bp->c_next;
281: cfreecount -= CBSIZE;
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;
293: cfreecount -= CBSIZE;
294: bp->c_next = NULL;
295: cq = bp->c_info;
296: }
297: nc = MIN(cc, sizeof (struct cblock) - ((int)cq & CROUND));
298: (void) bcopy(cp, cq, (unsigned)nc);
299: cp += nc;
300: cq += nc;
301: cc -= nc;
302: }
303: out:
304: q->c_cl = cq;
305: q->c_cc += acc - cc;
306: splx(s);
307: return (cc);
308: }
309:
310: /*
311: * Given a non-NULL pointter into the list (like c_cf which
312: * always points to a real character if non-NULL) return the pointer
313: * to the next character in the list or return NULL if no more chars.
314: *
315: * Callers must not allow getc's to happen between nextc's so that the
316: * pointer becomes invalid. Note that interrupts are NOT masked.
317: */
318: char *
319: nextc(p, cp)
320: register struct clist *p;
321: register char *cp;
322: {
323:
324: if (p->c_cc && ++cp != p->c_cl) {
325: if (((int)cp & CROUND) == 0)
326: return (((struct cblock *)cp)[-1].c_next->c_info);
327: return (cp);
328: }
329: return (0);
330: }
331:
332: /*
333: * Remove the last character in the list and return it.
334: */
335: unputc(p)
336: register struct clist *p;
337: {
338: register struct cblock *bp;
339: register int c, s;
340: struct cblock *obp;
341:
342: s = spltty();
343: if (p->c_cc <= 0)
344: c = -1;
345: else {
346: c = *--p->c_cl;
347: if (--p->c_cc <= 0) {
348: bp = (struct cblock *)p->c_cl;
349: bp = (struct cblock *)((int)bp & ~CROUND);
350: p->c_cl = p->c_cf = NULL;
351: bp->c_next = cfreelist;
352: cfreelist = bp;
353: cfreecount += CBSIZE;
354: } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) {
355: p->c_cl = (char *)((int)p->c_cl & ~CROUND);
356: bp = (struct cblock *)p->c_cf;
357: bp = (struct cblock *)((int)bp & ~CROUND);
358: while (bp->c_next != (struct cblock *)p->c_cl)
359: bp = bp->c_next;
360: obp = bp;
361: p->c_cl = (char *)(bp + 1);
362: bp = bp->c_next;
363: bp->c_next = cfreelist;
364: cfreelist = bp;
365: cfreecount += CBSIZE;
366: obp->c_next = NULL;
367: }
368: }
369: splx(s);
370: return (c);
371: }
372:
373: /*
374: * Put the chars in the from que
375: * on the end of the to que.
376: */
377: catq(from, to)
378: struct clist *from, *to;
379: {
380: char bbuf[CBSIZE*4];
381: register s, c;
382:
383: s = spltty();
384: if (to->c_cc == 0) {
385: *to = *from;
386: from->c_cc = 0;
387: from->c_cf = NULL;
388: from->c_cl = NULL;
389: splx(s);
390: return;
391: }
392: splx(s);
393: while (from->c_cc > 0) {
394: c = q_to_b(from, bbuf, sizeof bbuf);
395: (void) b_to_q(bbuf, c, to);
396: }
397: }
398:
399: #ifdef unneeded
400: /*
401: * Integer (short) get/put using clists.
402: * Note dependency on byte order.
403: */
404: typedef u_short word_t;
405:
406: getw(p)
407: register struct clist *p;
408: {
409: register int s, c;
410: register struct cblock *bp;
411:
412: if (p->c_cc <= 1)
413: return(-1);
414: if (p->c_cc & 01) {
415: c = getc(p);
416: #if defined(vax)
417: return (c | (getc(p)<<8));
418: #else
419: return (getc(p) | (c<<8));
420: #endif
421: }
422: s = spltty();
423: #if defined(vax)
424: c = *((word_t *)p->c_cf);
425: #else
426: c = (((u_char *)p->c_cf)[1] << 8) | ((u_char *)p->c_cf)[0];
427: #endif
428: p->c_cf += sizeof (word_t);
429: p->c_cc -= sizeof (word_t);
430: if (p->c_cc <= 0) {
431: bp = (struct cblock *)(p->c_cf-1);
432: bp = (struct cblock *)((int)bp & ~CROUND);
433: p->c_cf = NULL;
434: p->c_cl = NULL;
435: bp->c_next = cfreelist;
436: cfreelist = bp;
437: cfreecount += CBSIZE;
438: if (cwaiting) {
439: wakeup(&cwaiting);
440: cwaiting = 0;
441: }
442: } else if (((int)p->c_cf & CROUND) == 0) {
443: bp = (struct cblock *)(p->c_cf);
444: bp--;
445: p->c_cf = bp->c_next->c_info;
446: bp->c_next = cfreelist;
447: cfreelist = bp;
448: cfreecount += CBSIZE;
449: if (cwaiting) {
450: wakeup(&cwaiting);
451: cwaiting = 0;
452: }
453: }
454: splx(s);
455: return (c);
456: }
457:
458: putw(c, p)
459: register struct clist *p;
460: word_t c;
461: {
462: register s;
463: register struct cblock *bp;
464: register char *cp;
465:
466: s = spltty();
467: if (cfreelist==NULL) {
468: splx(s);
469: return(-1);
470: }
471: if (p->c_cc & 01) {
472: #if defined(vax)
473: (void) putc(c, p);
474: (void) putc(c>>8, p);
475: #else
476: (void) putc(c>>8, p);
477: (void) putc(c, p);
478: #endif
479: } else {
480: if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
481: if ((bp = cfreelist) == NULL) {
482: splx(s);
483: return (-1);
484: }
485: cfreelist = bp->c_next;
486: cfreecount -= CBSIZE;
487: bp->c_next = NULL;
488: p->c_cf = cp = bp->c_info;
489: } else if (((int)cp & CROUND) == 0) {
490: bp = (struct cblock *)cp - 1;
491: if ((bp->c_next = cfreelist) == NULL) {
492: splx(s);
493: return (-1);
494: }
495: bp = bp->c_next;
496: cfreelist = bp->c_next;
497: cfreecount -= CBSIZE;
498: bp->c_next = NULL;
499: cp = bp->c_info;
500: }
501: #if defined(vax)
502: *(word_t *)cp = c;
503: #else
504: ((u_char *)cp)[0] = c>>8;
505: ((u_char *)cp)[1] = c;
506: #endif
507: p->c_cl = cp + sizeof (word_t);
508: p->c_cc += sizeof (word_t);
509: }
510: splx(s);
511: return (0);
512: }
513: #endif unneeded
Defined functions
catq
defined in line
377; used 2 times
getc
defined in line
21; used 3 times
getw
defined in line
406;
never used
ndqb
defined in line
131; used 10 times
putc
defined in line
223; used 22 times
- in line 473-477(4)
- in /usr/src/sys/net/if_sl.c line
287,
316-318(2),
332,
341
- in /usr/src/sys/sys/tty.c line
193,
730,
835,
894,
916,
974,
1032,
1106-1111(2),
1247
- in /usr/src/sys/sys/tty_pty.c line
416
- in /usr/src/sys/vaxuba/ct.c line
138
- in /usr/src/sys/vaxuba/lp.c line
279
putw
defined in line
458;
never used
Defined variables
Defined typedef's