X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/81263dbac5438382d44727be195f8a206dc7e766..4a404244ad5a6e8679d302ed44ecc61cac172725:/usr/src/sys/kern/tty_subr.c diff --git a/usr/src/sys/kern/tty_subr.c b/usr/src/sys/kern/tty_subr.c index 30a6a7d71b..78ce16f4b2 100644 --- a/usr/src/sys/kern/tty_subr.c +++ b/usr/src/sys/kern/tty_subr.c @@ -1,18 +1,13 @@ -/* tty_subr.c 3.2 %H% */ +/* tty_subr.c 4.15 82/03/14 */ #include "../h/param.h" -#include "../h/tty.h" #include "../h/systm.h" #include "../h/conf.h" #include "../h/buf.h" +#include "../h/tty.h" +#include "../h/clist.h" -struct cblock { - struct cblock *c_next; - char c_info[CBSIZE]; -}; - -struct cblock cfree[NCLIST]; -struct cblock *cfreelist; +char cwaiting; /* * Character list get/put @@ -23,7 +18,7 @@ register struct clist *p; register struct cblock *bp; register int c, s; - s = spl6(); + s = spl5(); if (p->c_cc <= 0) { c = -1; p->c_cc = 0; @@ -37,18 +32,29 @@ register struct clist *p; p->c_cl = NULL; bp->c_next = cfreelist; cfreelist = bp; + cfreecount += CBSIZE; + if (cwaiting) { + wakeup(&cwaiting); + cwaiting = 0; + } } else if (((int)p->c_cf & CROUND) == 0){ bp = (struct cblock *)(p->c_cf); bp--; p->c_cf = bp->c_next->c_info; bp->c_next = cfreelist; cfreelist = bp; + cfreecount += CBSIZE; + if (cwaiting) { + wakeup(&cwaiting); + cwaiting = 0; + } } } splx(s); return(c); } +#if notdef /* * copy clist to buffer. * return number of bytes moved. @@ -63,10 +69,11 @@ register char *cp; if (cc <= 0) return(0); - s = spl6(); + s = spl5(); if (q->c_cc <= 0) { q->c_cc = 0; q->c_cf = q->c_cl = NULL; + splx(s); return(0); } acp = cp; @@ -80,6 +87,11 @@ register char *cp; q->c_cf = q->c_cl = NULL; bp->c_next = cfreelist; cfreelist = bp; + cfreecount += CBSIZE; + if (cwaiting) { + wakeup(&cwaiting); + cwaiting = 0; + } break; } if (((int)q->c_cf & CROUND) == 0) { @@ -88,12 +100,17 @@ register char *cp; q->c_cf = bp->c_next->c_info; bp->c_next = cfreelist; cfreelist = bp; + cfreecount += CBSIZE; + if (cwaiting) { + wakeup(&cwaiting); + cwaiting = 0; + } } } splx(s); return(cp-acp); } - +#endif /* * Return count of contiguous characters @@ -106,7 +123,7 @@ register struct clist *q; register cc; int s; - s = spl6(); + s = spl5(); if (q->c_cc <= 0) { cc = -q->c_cc; goto out; @@ -123,7 +140,8 @@ int s; end += cc; while (p < end) { if (*p & flag) { - cc = (int)p - (int)q->c_cf; + cc = (int)p; + cc -= (int)q->c_cf; break; } p++; @@ -137,55 +155,68 @@ out: /* - * Update clist to show that cc characters - * were removed. It is assumed that cc < CBSIZE. + * Flush cc bytes from q. */ ndflush(q, cc) register struct clist *q; register cc; { +register struct cblock *bp; +char *end; +int rem; register s; - if (cc == 0) - return; - s = spl6(); + s = spl5(); if (q->c_cc < 0) { - if (q->c_cf != NULL) { - q->c_cc += cc; - q->c_cf += cc; - goto out; - } - q->c_cc = 0; + printf("neg q flush\n"); goto out; } if (q->c_cc == 0) { goto out; } - q->c_cc -= cc; - q->c_cf += cc; - if (((int)q->c_cf & CROUND) == 0) { - register struct cblock *bp; - - bp = (struct cblock *)(q->c_cf) -1; - if (bp->c_next) { + while (cc>0 && q->c_cc) { + bp = (struct cblock *)((int)q->c_cf & ~CROUND); + if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) { + end = q->c_cl; + } else { + end = (char *)((int)bp + sizeof (struct cblock)); + } + rem = end - q->c_cf; + if (cc >= rem) { + cc -= rem; + q->c_cc -= rem; q->c_cf = bp->c_next->c_info; + bp->c_next = cfreelist; + cfreelist = bp; + cfreecount += CBSIZE; + if (cwaiting) { + wakeup(&cwaiting); + cwaiting = 0; + } } else { - q->c_cf = q->c_cl = NULL; + q->c_cc -= cc; + q->c_cf += cc; + if (q->c_cc <= 0) { + bp->c_next = cfreelist; + cfreelist = bp; + cfreecount += CBSIZE; + if (cwaiting) { + wakeup(&cwaiting); + cwaiting = 0; + } + } + break; } - bp->c_next = cfreelist; - cfreelist = bp; - } else - if (q->c_cc == 0) { - register struct cblock *bp; - q->c_cf = (char *)((int)q->c_cf & ~CROUND); - bp = (struct cblock *)(q->c_cf); - bp->c_next = cfreelist; - cfreelist = bp; + } + if (q->c_cc <= 0) { q->c_cf = q->c_cl = NULL; + q->c_cc = 0; } out: splx(s); } + + putc(c, p) register struct clist *p; { @@ -193,13 +224,14 @@ register struct clist *p; register char *cp; register s; - s = spl6(); + s = spl5(); if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) { if ((bp = cfreelist) == NULL) { splx(s); return(-1); } cfreelist = bp->c_next; + cfreecount -= CBSIZE; bp->c_next = NULL; p->c_cf = cp = bp->c_info; } else if (((int)cp & CROUND) == 0) { @@ -210,6 +242,7 @@ register struct clist *p; } bp = bp->c_next; cfreelist = bp->c_next; + cfreecount -= CBSIZE; bp->c_next = NULL; cp = bp->c_info; } @@ -238,11 +271,14 @@ register int cc; if (cc <= 0) return(0); acc = cc; - s = spl6(); + + + s = spl5(); if ((cq = q->c_cl) == NULL || q->c_cc < 0) { if ((bp = cfreelist) == NULL) goto out; cfreelist = bp->c_next; + cfreecount -= CBSIZE; bp->c_next = NULL; q->c_cf = cq = bp->c_info; } @@ -254,6 +290,7 @@ register int cc; goto out; bp = bp->c_next; cfreelist = bp->c_next; + cfreecount -= CBSIZE; bp->c_next = NULL; cq = bp->c_info; } @@ -268,32 +305,89 @@ out: } /* - * Initialize clist by freeing all character blocks, then count - * number of character devices. (Once-only routine) + * Given a non-NULL pointter into the list (like c_cf which + * always points to a real character if non-NULL) return the pointer + * to the next character in the list or return NULL if no more chars. + * + * Callers must not allow getc's to happen between nextc's so that the + * pointer becomes invalid. Note that interrupts are NOT masked. */ -cinit() +char * +nextc(p, cp) +register struct clist *p; +register char *cp; { - register int ccp; - register struct cblock *cp; - register struct cdevsw *cdp; - - ccp = (int)cfree; - ccp = (ccp+CROUND) & ~CROUND; - for(cp=(struct cblock *)ccp; cp <= &cfree[NCLIST-1]; cp++) { - cp->c_next = cfreelist; - cfreelist = cp; + + if (p->c_cc && ++cp != p->c_cl) { + if (((int)cp & CROUND) == 0) + return (((struct cblock *)cp)[-1].c_next->c_info); + return (cp); + } + return (0); +} + +/* + * Remove the last character in the list and return it. + */ +unputc(p) +register struct clist *p; +{ + register struct cblock *bp; + register int c, s; + struct cblock *obp; + + s = spl5(); + if (p->c_cc <= 0) + c = -1; + else { + c = *--p->c_cl; + if (--p->c_cc <= 0) { + bp = (struct cblock *)p->c_cl; + bp = (struct cblock *)((int)bp & ~CROUND); + p->c_cl = p->c_cf = NULL; + bp->c_next = cfreelist; + cfreelist = bp; + cfreecount += CBSIZE; + } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) { + p->c_cl = (char *)((int)p->c_cl & ~CROUND); + bp = (struct cblock *)p->c_cf; + bp = (struct cblock *)((int)bp & ~CROUND); + while (bp->c_next != (struct cblock *)p->c_cl) + bp = bp->c_next; + obp = bp; + p->c_cl = (char *)(bp + 1); + bp = bp->c_next; + bp->c_next = cfreelist; + cfreelist = bp; + cfreecount += CBSIZE; + obp->c_next = NULL; + } } - ccp = 0; - for(cdp = cdevsw; cdp->d_open; cdp++) - ccp++; - nchrdev = ccp; + splx(s); + return (c); } +/* + * Put the chars in the from que + * on the end of the to que. + * + * SHOULD JUST USE q_to_b AND THEN b_to_q HERE. + */ +catq(from, to) +struct clist *from, *to; +{ + register c; + + while ((c = getc(from)) >= 0) + (void) putc(c, to); +} + +#include "dmc.h" +#if NDMC > 0 /* * integer (2-byte) get/put * using clists */ -/* getw(p) register struct clist *p; { @@ -304,14 +398,13 @@ register struct clist *p; s = getc(p); return(s | (getc(p)<<8)); } -*/ putw(c, p) register struct clist *p; { register s; - s = spl6(); + s = spl5(); if (cfreelist==NULL) { splx(s); return(-1); @@ -321,3 +414,4 @@ register struct clist *p; splx(s); return(0); } +#endif