1*17576Sbloom /* tty_subr.c 6.8 84/12/21 */ 21892Swnj 317097Sbloom #include "param.h" 417097Sbloom #include "systm.h" 517097Sbloom #include "conf.h" 617097Sbloom #include "buf.h" 7*17576Sbloom #include "ioctl.h" 817097Sbloom #include "tty.h" 917097Sbloom #include "clist.h" 1032Sbill 111890Swnj char cwaiting; 121890Swnj 1332Sbill /* 1432Sbill * Character list get/put 1532Sbill */ 1632Sbill getc(p) 1712754Ssam register struct clist *p; 1832Sbill { 1932Sbill register struct cblock *bp; 2032Sbill register int c, s; 2132Sbill 2217542Skarels s = spltty(); 2332Sbill if (p->c_cc <= 0) { 2432Sbill c = -1; 2532Sbill p->c_cc = 0; 2632Sbill p->c_cf = p->c_cl = NULL; 2732Sbill } else { 2832Sbill c = *p->c_cf++ & 0377; 2932Sbill if (--p->c_cc<=0) { 3032Sbill bp = (struct cblock *)(p->c_cf-1); 3132Sbill bp = (struct cblock *) ((int)bp & ~CROUND); 3232Sbill p->c_cf = NULL; 3332Sbill p->c_cl = NULL; 3432Sbill bp->c_next = cfreelist; 3532Sbill cfreelist = bp; 361890Swnj cfreecount += CBSIZE; 371890Swnj if (cwaiting) { 381890Swnj wakeup(&cwaiting); 391890Swnj cwaiting = 0; 401890Swnj } 4132Sbill } else if (((int)p->c_cf & CROUND) == 0){ 4232Sbill bp = (struct cblock *)(p->c_cf); 4332Sbill bp--; 4432Sbill p->c_cf = bp->c_next->c_info; 4532Sbill bp->c_next = cfreelist; 4632Sbill cfreelist = bp; 471890Swnj cfreecount += CBSIZE; 481890Swnj if (cwaiting) { 491890Swnj wakeup(&cwaiting); 501890Swnj cwaiting = 0; 511890Swnj } 5232Sbill } 5332Sbill } 5432Sbill splx(s); 5532Sbill return(c); 5632Sbill } 5732Sbill 5832Sbill /* 5932Sbill * copy clist to buffer. 6032Sbill * return number of bytes moved. 6132Sbill */ 6232Sbill q_to_b(q, cp, cc) 639761Ssam register struct clist *q; 649761Ssam register char *cp; 6532Sbill { 6632Sbill register struct cblock *bp; 6732Sbill register int s; 6817542Skarels register nc; 6932Sbill char *acp; 7032Sbill 7132Sbill if (cc <= 0) 7232Sbill return(0); 7317542Skarels s = spltty(); 7432Sbill if (q->c_cc <= 0) { 7532Sbill q->c_cc = 0; 7632Sbill q->c_cf = q->c_cl = NULL; 771890Swnj splx(s); 7832Sbill return(0); 7932Sbill } 8032Sbill acp = cp; 8132Sbill 8217542Skarels while (cc) { 8317542Skarels nc = sizeof(struct cblock) - ((int)q->c_cf & CROUND); 8417542Skarels nc = MIN(nc, cc); 8517542Skarels nc = MIN(nc, q->c_cc); 8617542Skarels (void) bcopy(q->c_cf, cp, (unsigned)nc); 8717542Skarels q->c_cf += nc; 8817542Skarels q->c_cc -= nc; 8917542Skarels cc -= nc; 9017542Skarels cp += nc; 9117542Skarels if (q->c_cc <= 0) { 9217542Skarels bp = (struct cblock *)(q->c_cf - 1); 9332Sbill bp = (struct cblock *)((int)bp & ~CROUND); 9432Sbill q->c_cf = q->c_cl = NULL; 9532Sbill bp->c_next = cfreelist; 9632Sbill cfreelist = bp; 971890Swnj cfreecount += CBSIZE; 981890Swnj if (cwaiting) { 991890Swnj wakeup(&cwaiting); 1001890Swnj cwaiting = 0; 1011890Swnj } 10232Sbill break; 10332Sbill } 10432Sbill if (((int)q->c_cf & CROUND) == 0) { 10532Sbill bp = (struct cblock *)(q->c_cf); 10632Sbill bp--; 10732Sbill q->c_cf = bp->c_next->c_info; 10832Sbill bp->c_next = cfreelist; 10932Sbill cfreelist = bp; 1101890Swnj cfreecount += CBSIZE; 1111890Swnj if (cwaiting) { 1121890Swnj wakeup(&cwaiting); 1131890Swnj cwaiting = 0; 1141890Swnj } 11532Sbill } 11632Sbill } 11732Sbill splx(s); 11832Sbill return(cp-acp); 11932Sbill } 12032Sbill 12132Sbill /* 12232Sbill * Return count of contiguous characters 12332Sbill * in clist starting at q->c_cf. 12432Sbill * Stop counting if flag&character is non-null. 12532Sbill */ 12632Sbill ndqb(q, flag) 1279761Ssam register struct clist *q; 12832Sbill { 1299761Ssam register cc; 1309761Ssam int s; 13132Sbill 13217542Skarels s = spltty(); 13332Sbill if (q->c_cc <= 0) { 13432Sbill cc = -q->c_cc; 13532Sbill goto out; 13632Sbill } 13732Sbill cc = ((int)q->c_cf + CBSIZE) & ~CROUND; 13832Sbill cc -= (int)q->c_cf; 13932Sbill if (q->c_cc < cc) 14032Sbill cc = q->c_cc; 14132Sbill if (flag) { 14232Sbill register char *p, *end; 14332Sbill 14432Sbill p = q->c_cf; 14532Sbill end = p; 14632Sbill end += cc; 14732Sbill while (p < end) { 14832Sbill if (*p & flag) { 1491890Swnj cc = (int)p; 1501890Swnj cc -= (int)q->c_cf; 15132Sbill break; 15232Sbill } 15332Sbill p++; 15432Sbill } 15532Sbill } 15632Sbill out: 15732Sbill splx(s); 15832Sbill return(cc); 15932Sbill } 16032Sbill 1611890Swnj 1621890Swnj 16332Sbill /* 1641890Swnj * Flush cc bytes from q. 16532Sbill */ 16632Sbill ndflush(q, cc) 16712754Ssam register struct clist *q; 16812754Ssam register cc; 16932Sbill { 17012754Ssam register struct cblock *bp; 17112754Ssam char *end; 17212754Ssam int rem, s; 17332Sbill 17417542Skarels s = spltty(); 17510749Seric if (q->c_cc <= 0) { 17632Sbill goto out; 17732Sbill } 1781890Swnj while (cc>0 && q->c_cc) { 1791890Swnj bp = (struct cblock *)((int)q->c_cf & ~CROUND); 1801890Swnj if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) { 1811890Swnj end = q->c_cl; 1821890Swnj } else { 1831890Swnj end = (char *)((int)bp + sizeof (struct cblock)); 1841890Swnj } 1851890Swnj rem = end - q->c_cf; 1861890Swnj if (cc >= rem) { 1871890Swnj cc -= rem; 1881890Swnj q->c_cc -= rem; 18932Sbill q->c_cf = bp->c_next->c_info; 1901890Swnj bp->c_next = cfreelist; 1911890Swnj cfreelist = bp; 1921890Swnj cfreecount += CBSIZE; 1931890Swnj if (cwaiting) { 1941890Swnj wakeup(&cwaiting); 1951890Swnj cwaiting = 0; 1961890Swnj } 19732Sbill } else { 1981890Swnj q->c_cc -= cc; 1991890Swnj q->c_cf += cc; 2001890Swnj if (q->c_cc <= 0) { 2011890Swnj bp->c_next = cfreelist; 2021890Swnj cfreelist = bp; 2031890Swnj cfreecount += CBSIZE; 2041890Swnj if (cwaiting) { 2051890Swnj wakeup(&cwaiting); 2061890Swnj cwaiting = 0; 2071890Swnj } 2081890Swnj } 2091890Swnj break; 21032Sbill } 2111890Swnj } 2121890Swnj if (q->c_cc <= 0) { 21332Sbill q->c_cf = q->c_cl = NULL; 2141890Swnj q->c_cc = 0; 21532Sbill } 21632Sbill out: 21732Sbill splx(s); 21832Sbill } 219172Sbill 2201890Swnj 22132Sbill putc(c, p) 22212754Ssam register struct clist *p; 22332Sbill { 22432Sbill register struct cblock *bp; 22532Sbill register char *cp; 22632Sbill register s; 22732Sbill 22817542Skarels s = spltty(); 22932Sbill if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) { 23032Sbill if ((bp = cfreelist) == NULL) { 23132Sbill splx(s); 23232Sbill return(-1); 23332Sbill } 23432Sbill cfreelist = bp->c_next; 2351890Swnj cfreecount -= CBSIZE; 23632Sbill bp->c_next = NULL; 23732Sbill p->c_cf = cp = bp->c_info; 23832Sbill } else if (((int)cp & CROUND) == 0) { 23932Sbill bp = (struct cblock *)cp - 1; 24032Sbill if ((bp->c_next = cfreelist) == NULL) { 24132Sbill splx(s); 24232Sbill return(-1); 24332Sbill } 24432Sbill bp = bp->c_next; 24532Sbill cfreelist = bp->c_next; 2461890Swnj cfreecount -= CBSIZE; 24732Sbill bp->c_next = NULL; 24832Sbill cp = bp->c_info; 24932Sbill } 25032Sbill *cp++ = c; 25132Sbill p->c_cc++; 25232Sbill p->c_cl = cp; 25332Sbill splx(s); 25432Sbill return(0); 25532Sbill } 25632Sbill 2571890Swnj 2581890Swnj 25932Sbill /* 26032Sbill * copy buffer to clist. 26132Sbill * return number of bytes not transfered. 26232Sbill */ 26332Sbill b_to_q(cp, cc, q) 26412754Ssam register char *cp; 26512754Ssam struct clist *q; 26612754Ssam register int cc; 26732Sbill { 26832Sbill register char *cq; 26932Sbill register struct cblock *bp; 27017542Skarels register s, nc; 27117542Skarels int acc; 27232Sbill 27332Sbill if (cc <= 0) 27417542Skarels return(0); 27517542Skarels acc = cc; 27617542Skarels s = spltty(); 27717542Skarels if ((cq = q->c_cl) == NULL || q->c_cc < 0) { 27817542Skarels if ((bp = cfreelist) == NULL) 27917542Skarels goto out; 28017542Skarels cfreelist = bp->c_next; 28117542Skarels cfreecount -= CBSIZE; 28217542Skarels bp->c_next = NULL; 28317542Skarels q->c_cf = cq = bp->c_info; 28417542Skarels } 28517542Skarels 28617542Skarels while (cc) { 28732Sbill if (((int)cq & CROUND) == 0) { 28817542Skarels bp = (struct cblock *) cq - 1; 28917542Skarels if ((bp->c_next = cfreelist) == NULL) 29017542Skarels goto out; 29132Sbill bp = bp->c_next; 29232Sbill cfreelist = bp->c_next; 2931890Swnj cfreecount -= CBSIZE; 29432Sbill bp->c_next = NULL; 29517542Skarels cq = bp->c_info; 29632Sbill } 29717542Skarels nc = MIN(cc, sizeof(struct cblock) - ((int)cq & CROUND)); 29817542Skarels (void) bcopy(cp, cq, (unsigned)nc); 29917542Skarels cp += nc; 30017542Skarels cq += nc; 30117542Skarels cc -= nc; 30232Sbill } 30317542Skarels out: 30417542Skarels q->c_cl = cq; 30517542Skarels q->c_cc += acc - cc; 30617542Skarels splx(s); 30717368Ssam return (cc); 30832Sbill } 30932Sbill 31032Sbill /* 311172Sbill * Given a non-NULL pointter into the list (like c_cf which 312172Sbill * always points to a real character if non-NULL) return the pointer 313172Sbill * to the next character in the list or return NULL if no more chars. 314172Sbill * 315172Sbill * Callers must not allow getc's to happen between nextc's so that the 316172Sbill * pointer becomes invalid. Note that interrupts are NOT masked. 317172Sbill */ 318172Sbill char * 319172Sbill nextc(p, cp) 32012754Ssam register struct clist *p; 32112754Ssam register char *cp; 322172Sbill { 323172Sbill 324172Sbill if (p->c_cc && ++cp != p->c_cl) { 325172Sbill if (((int)cp & CROUND) == 0) 326172Sbill return (((struct cblock *)cp)[-1].c_next->c_info); 327172Sbill return (cp); 328172Sbill } 329172Sbill return (0); 330172Sbill } 331172Sbill 332172Sbill /* 333172Sbill * Remove the last character in the list and return it. 334172Sbill */ 335172Sbill unputc(p) 33612754Ssam register struct clist *p; 337172Sbill { 338172Sbill register struct cblock *bp; 339172Sbill register int c, s; 340172Sbill struct cblock *obp; 341172Sbill 34217542Skarels s = spltty(); 343172Sbill if (p->c_cc <= 0) 344172Sbill c = -1; 345172Sbill else { 346172Sbill c = *--p->c_cl; 347172Sbill if (--p->c_cc <= 0) { 348172Sbill bp = (struct cblock *)p->c_cl; 349172Sbill bp = (struct cblock *)((int)bp & ~CROUND); 350172Sbill p->c_cl = p->c_cf = NULL; 351172Sbill bp->c_next = cfreelist; 352172Sbill cfreelist = bp; 3531890Swnj cfreecount += CBSIZE; 354172Sbill } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) { 355172Sbill p->c_cl = (char *)((int)p->c_cl & ~CROUND); 356172Sbill bp = (struct cblock *)p->c_cf; 357172Sbill bp = (struct cblock *)((int)bp & ~CROUND); 358172Sbill while (bp->c_next != (struct cblock *)p->c_cl) 359172Sbill bp = bp->c_next; 360172Sbill obp = bp; 361172Sbill p->c_cl = (char *)(bp + 1); 362172Sbill bp = bp->c_next; 363172Sbill bp->c_next = cfreelist; 364172Sbill cfreelist = bp; 3651890Swnj cfreecount += CBSIZE; 366172Sbill obp->c_next = NULL; 367172Sbill } 368172Sbill } 369172Sbill splx(s); 370172Sbill return (c); 371172Sbill } 372172Sbill 373172Sbill /* 374172Sbill * Put the chars in the from que 375172Sbill * on the end of the to que. 376172Sbill */ 377172Sbill catq(from, to) 37812754Ssam struct clist *from, *to; 379172Sbill { 38017542Skarels char bbuf[CBSIZE*4]; 38117542Skarels register s, c; 382172Sbill 38317542Skarels s = spltty(); 38417542Skarels if (to->c_cc == 0) { 38517542Skarels *to = *from; 38617542Skarels from->c_cc = 0; 38717542Skarels from->c_cf = NULL; 38817542Skarels from->c_cl = NULL; 38917542Skarels splx(s); 39017542Skarels return; 39117542Skarels } 39217542Skarels splx(s); 39317542Skarels while (from->c_cc > 0) { 39417542Skarels c = q_to_b(from, bbuf, sizeof bbuf); 39517542Skarels (void) b_to_q(bbuf, c, to); 39617542Skarels } 397172Sbill } 398172Sbill 39917542Skarels #ifdef unneeded 400172Sbill /* 4019761Ssam * Integer (short) get/put 40232Sbill * using clists 40332Sbill */ 40417542Skarels typedef u_short word_t; 4059761Ssam 40632Sbill getw(p) 4078955Sroot register struct clist *p; 40832Sbill { 40917542Skarels register int s, c; 41017542Skarels register struct cblock *bp; 41132Sbill 41217542Skarels if (p->c_cc <= 1) 41317542Skarels return(-1); 41417542Skarels if (p->c_cc & 01) { 41517542Skarels c = getc(p); 41617542Skarels return(c | (getc(p)<<8)); 41717542Skarels } 41817542Skarels s = spltty(); 41917542Skarels c = *((word_t *)p->c_cf); 42017542Skarels p->c_cf += sizeof(word_t); 42117542Skarels p->c_cc -= sizeof(word_t); 42217542Skarels if (p->c_cc <= 0) { 42317542Skarels bp = (struct cblock *)(p->c_cf-1); 42417542Skarels bp = (struct cblock *) ((int)bp & ~CROUND); 42517542Skarels p->c_cf = NULL; 42617542Skarels p->c_cl = NULL; 42717542Skarels bp->c_next = cfreelist; 42817542Skarels cfreelist = bp; 42917542Skarels cfreecount += CBSIZE; 43017542Skarels if (cwaiting) { 43117542Skarels wakeup(&cwaiting); 43217542Skarels cwaiting = 0; 43317542Skarels } 43417542Skarels } else if (((int)p->c_cf & CROUND) == 0) { 43517542Skarels bp = (struct cblock *)(p->c_cf); 43617542Skarels bp--; 43717542Skarels p->c_cf = bp->c_next->c_info; 43817542Skarels bp->c_next = cfreelist; 43917542Skarels cfreelist = bp; 44017542Skarels cfreecount += CBSIZE; 44117542Skarels if (cwaiting) { 44217542Skarels wakeup(&cwaiting); 44317542Skarels cwaiting = 0; 44417542Skarels } 44517542Skarels } 44617542Skarels splx(s); 44717542Skarels return (c); 44832Sbill } 44932Sbill 45032Sbill putw(c, p) 4518955Sroot register struct clist *p; 45217542Skarels word_t c; 45332Sbill { 45432Sbill register s; 45517542Skarels register struct cblock *bp; 45617542Skarels register char *cp; 45732Sbill 45817542Skarels s = spltty(); 45932Sbill if (cfreelist==NULL) { 46032Sbill splx(s); 46132Sbill return(-1); 46232Sbill } 46317542Skarels if (p->c_cc & 01) { 46417542Skarels (void) putc(c, p); 46517542Skarels (void) putc(c>>8, p); 46617542Skarels } else { 46717542Skarels if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) { 46817542Skarels if ((bp = cfreelist) == NULL) { 46917542Skarels splx(s); 47017542Skarels return (-1); 47117542Skarels } 47217542Skarels cfreelist = bp->c_next; 47317542Skarels cfreecount -= CBSIZE; 47417542Skarels bp->c_next = NULL; 47517542Skarels p->c_cf = cp = bp->c_info; 47617542Skarels } else if (((int)cp & CROUND) == 0) { 47717542Skarels bp = (struct cblock *)cp - 1; 47817542Skarels if ((bp->c_next = cfreelist) == NULL) { 47917542Skarels splx(s); 48017542Skarels return (-1); 48117542Skarels } 48217542Skarels bp = bp->c_next; 48317542Skarels cfreelist = bp->c_next; 48417542Skarels cfreecount -= CBSIZE; 48517542Skarels bp->c_next = NULL; 48617542Skarels cp = bp->c_info; 48717542Skarels } 48817542Skarels *(word_t *)cp = c; 48917542Skarels p->c_cl = cp + sizeof(word_t); 49017542Skarels p->c_cc += sizeof(word_t); 49117542Skarels } 49232Sbill splx(s); 4939761Ssam return (0); 49432Sbill } 49517542Skarels #endif unneeded 496