1*32Sbill /* tty_subr.c 3.1 10/14/12 */ 2*32Sbill 3*32Sbill #include "../h/param.h" 4*32Sbill #include "../h/tty.h" 5*32Sbill #include "../h/systm.h" 6*32Sbill #include "../h/conf.h" 7*32Sbill #include "../h/buf.h" 8*32Sbill 9*32Sbill struct cblock { 10*32Sbill struct cblock *c_next; 11*32Sbill char c_info[CBSIZE]; 12*32Sbill }; 13*32Sbill 14*32Sbill struct cblock cfree[NCLIST]; 15*32Sbill struct cblock *cfreelist; 16*32Sbill 17*32Sbill /* 18*32Sbill * Character list get/put 19*32Sbill */ 20*32Sbill getc(p) 21*32Sbill register struct clist *p; 22*32Sbill { 23*32Sbill register struct cblock *bp; 24*32Sbill register int c, s; 25*32Sbill 26*32Sbill s = spl6(); 27*32Sbill if (p->c_cc <= 0) { 28*32Sbill c = -1; 29*32Sbill p->c_cc = 0; 30*32Sbill p->c_cf = p->c_cl = NULL; 31*32Sbill } else { 32*32Sbill c = *p->c_cf++ & 0377; 33*32Sbill if (--p->c_cc<=0) { 34*32Sbill bp = (struct cblock *)(p->c_cf-1); 35*32Sbill bp = (struct cblock *) ((int)bp & ~CROUND); 36*32Sbill p->c_cf = NULL; 37*32Sbill p->c_cl = NULL; 38*32Sbill bp->c_next = cfreelist; 39*32Sbill cfreelist = bp; 40*32Sbill } else if (((int)p->c_cf & CROUND) == 0){ 41*32Sbill bp = (struct cblock *)(p->c_cf); 42*32Sbill bp--; 43*32Sbill p->c_cf = bp->c_next->c_info; 44*32Sbill bp->c_next = cfreelist; 45*32Sbill cfreelist = bp; 46*32Sbill } 47*32Sbill } 48*32Sbill splx(s); 49*32Sbill return(c); 50*32Sbill } 51*32Sbill 52*32Sbill /* 53*32Sbill * copy clist to buffer. 54*32Sbill * return number of bytes moved. 55*32Sbill */ 56*32Sbill q_to_b(q, cp, cc) 57*32Sbill register struct clist *q; 58*32Sbill register char *cp; 59*32Sbill { 60*32Sbill register struct cblock *bp; 61*32Sbill register int s; 62*32Sbill char *acp; 63*32Sbill 64*32Sbill if (cc <= 0) 65*32Sbill return(0); 66*32Sbill s = spl6(); 67*32Sbill if (q->c_cc <= 0) { 68*32Sbill q->c_cc = 0; 69*32Sbill q->c_cf = q->c_cl = NULL; 70*32Sbill return(0); 71*32Sbill } 72*32Sbill acp = cp; 73*32Sbill cc++; 74*32Sbill 75*32Sbill while (--cc) { 76*32Sbill *cp++ = *q->c_cf++; 77*32Sbill if (--q->c_cc <= 0) { 78*32Sbill bp = (struct cblock *)(q->c_cf-1); 79*32Sbill bp = (struct cblock *)((int)bp & ~CROUND); 80*32Sbill q->c_cf = q->c_cl = NULL; 81*32Sbill bp->c_next = cfreelist; 82*32Sbill cfreelist = bp; 83*32Sbill break; 84*32Sbill } 85*32Sbill if (((int)q->c_cf & CROUND) == 0) { 86*32Sbill bp = (struct cblock *)(q->c_cf); 87*32Sbill bp--; 88*32Sbill q->c_cf = bp->c_next->c_info; 89*32Sbill bp->c_next = cfreelist; 90*32Sbill cfreelist = bp; 91*32Sbill } 92*32Sbill } 93*32Sbill splx(s); 94*32Sbill return(cp-acp); 95*32Sbill } 96*32Sbill 97*32Sbill 98*32Sbill /* 99*32Sbill * Return count of contiguous characters 100*32Sbill * in clist starting at q->c_cf. 101*32Sbill * Stop counting if flag&character is non-null. 102*32Sbill */ 103*32Sbill ndqb(q, flag) 104*32Sbill register struct clist *q; 105*32Sbill { 106*32Sbill register cc; 107*32Sbill int s; 108*32Sbill 109*32Sbill s = spl6(); 110*32Sbill if (q->c_cc <= 0) { 111*32Sbill cc = -q->c_cc; 112*32Sbill goto out; 113*32Sbill } 114*32Sbill cc = ((int)q->c_cf + CBSIZE) & ~CROUND; 115*32Sbill cc -= (int)q->c_cf; 116*32Sbill if (q->c_cc < cc) 117*32Sbill cc = q->c_cc; 118*32Sbill if (flag) { 119*32Sbill register char *p, *end; 120*32Sbill 121*32Sbill p = q->c_cf; 122*32Sbill end = p; 123*32Sbill end += cc; 124*32Sbill while (p < end) { 125*32Sbill if (*p & flag) { 126*32Sbill cc = (int)p - (int)q->c_cf; 127*32Sbill break; 128*32Sbill } 129*32Sbill p++; 130*32Sbill } 131*32Sbill } 132*32Sbill out: 133*32Sbill splx(s); 134*32Sbill return(cc); 135*32Sbill } 136*32Sbill 137*32Sbill 138*32Sbill 139*32Sbill /* 140*32Sbill * Update clist to show that cc characters 141*32Sbill * were removed. It is assumed that cc < CBSIZE. 142*32Sbill */ 143*32Sbill ndflush(q, cc) 144*32Sbill register struct clist *q; 145*32Sbill register cc; 146*32Sbill { 147*32Sbill register s; 148*32Sbill 149*32Sbill if (cc == 0) 150*32Sbill return; 151*32Sbill s = spl6(); 152*32Sbill if (q->c_cc < 0) { 153*32Sbill if (q->c_cf != NULL) { 154*32Sbill q->c_cc += cc; 155*32Sbill q->c_cf += cc; 156*32Sbill goto out; 157*32Sbill } 158*32Sbill q->c_cc = 0; 159*32Sbill goto out; 160*32Sbill } 161*32Sbill if (q->c_cc == 0) { 162*32Sbill goto out; 163*32Sbill } 164*32Sbill q->c_cc -= cc; 165*32Sbill q->c_cf += cc; 166*32Sbill if (((int)q->c_cf & CROUND) == 0) { 167*32Sbill register struct cblock *bp; 168*32Sbill 169*32Sbill bp = (struct cblock *)(q->c_cf) -1; 170*32Sbill if (bp->c_next) { 171*32Sbill q->c_cf = bp->c_next->c_info; 172*32Sbill } else { 173*32Sbill q->c_cf = q->c_cl = NULL; 174*32Sbill } 175*32Sbill bp->c_next = cfreelist; 176*32Sbill cfreelist = bp; 177*32Sbill } else 178*32Sbill if (q->c_cc == 0) { 179*32Sbill register struct cblock *bp; 180*32Sbill q->c_cf = (char *)((int)q->c_cf & ~CROUND); 181*32Sbill bp = (struct cblock *)(q->c_cf); 182*32Sbill bp->c_next = cfreelist; 183*32Sbill cfreelist = bp; 184*32Sbill q->c_cf = q->c_cl = NULL; 185*32Sbill } 186*32Sbill out: 187*32Sbill splx(s); 188*32Sbill } 189*32Sbill putc(c, p) 190*32Sbill register struct clist *p; 191*32Sbill { 192*32Sbill register struct cblock *bp; 193*32Sbill register char *cp; 194*32Sbill register s; 195*32Sbill 196*32Sbill s = spl6(); 197*32Sbill if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) { 198*32Sbill if ((bp = cfreelist) == NULL) { 199*32Sbill splx(s); 200*32Sbill return(-1); 201*32Sbill } 202*32Sbill cfreelist = bp->c_next; 203*32Sbill bp->c_next = NULL; 204*32Sbill p->c_cf = cp = bp->c_info; 205*32Sbill } else if (((int)cp & CROUND) == 0) { 206*32Sbill bp = (struct cblock *)cp - 1; 207*32Sbill if ((bp->c_next = cfreelist) == NULL) { 208*32Sbill splx(s); 209*32Sbill return(-1); 210*32Sbill } 211*32Sbill bp = bp->c_next; 212*32Sbill cfreelist = bp->c_next; 213*32Sbill bp->c_next = NULL; 214*32Sbill cp = bp->c_info; 215*32Sbill } 216*32Sbill *cp++ = c; 217*32Sbill p->c_cc++; 218*32Sbill p->c_cl = cp; 219*32Sbill splx(s); 220*32Sbill return(0); 221*32Sbill } 222*32Sbill 223*32Sbill 224*32Sbill 225*32Sbill /* 226*32Sbill * copy buffer to clist. 227*32Sbill * return number of bytes not transfered. 228*32Sbill */ 229*32Sbill b_to_q(cp, cc, q) 230*32Sbill register char *cp; 231*32Sbill struct clist *q; 232*32Sbill register int cc; 233*32Sbill { 234*32Sbill register char *cq; 235*32Sbill register struct cblock *bp; 236*32Sbill register s, acc; 237*32Sbill 238*32Sbill if (cc <= 0) 239*32Sbill return(0); 240*32Sbill acc = cc; 241*32Sbill s = spl6(); 242*32Sbill if ((cq = q->c_cl) == NULL || q->c_cc < 0) { 243*32Sbill if ((bp = cfreelist) == NULL) 244*32Sbill goto out; 245*32Sbill cfreelist = bp->c_next; 246*32Sbill bp->c_next = NULL; 247*32Sbill q->c_cf = cq = bp->c_info; 248*32Sbill } 249*32Sbill 250*32Sbill while (cc) { 251*32Sbill if (((int)cq & CROUND) == 0) { 252*32Sbill bp = (struct cblock *) cq - 1; 253*32Sbill if ((bp->c_next = cfreelist) == NULL) 254*32Sbill goto out; 255*32Sbill bp = bp->c_next; 256*32Sbill cfreelist = bp->c_next; 257*32Sbill bp->c_next = NULL; 258*32Sbill cq = bp->c_info; 259*32Sbill } 260*32Sbill *cq++ = *cp++; 261*32Sbill cc--; 262*32Sbill } 263*32Sbill out: 264*32Sbill q->c_cl = cq; 265*32Sbill q->c_cc += acc-cc; 266*32Sbill splx(s); 267*32Sbill return(cc); 268*32Sbill } 269*32Sbill 270*32Sbill /* 271*32Sbill * Initialize clist by freeing all character blocks, then count 272*32Sbill * number of character devices. (Once-only routine) 273*32Sbill */ 274*32Sbill cinit() 275*32Sbill { 276*32Sbill register int ccp; 277*32Sbill register struct cblock *cp; 278*32Sbill register struct cdevsw *cdp; 279*32Sbill 280*32Sbill ccp = (int)cfree; 281*32Sbill ccp = (ccp+CROUND) & ~CROUND; 282*32Sbill for(cp=(struct cblock *)ccp; cp <= &cfree[NCLIST-1]; cp++) { 283*32Sbill cp->c_next = cfreelist; 284*32Sbill cfreelist = cp; 285*32Sbill } 286*32Sbill ccp = 0; 287*32Sbill for(cdp = cdevsw; cdp->d_open; cdp++) 288*32Sbill ccp++; 289*32Sbill nchrdev = ccp; 290*32Sbill } 291*32Sbill 292*32Sbill /* 293*32Sbill * integer (2-byte) get/put 294*32Sbill * using clists 295*32Sbill */ 296*32Sbill /* 297*32Sbill getw(p) 298*32Sbill register struct clist *p; 299*32Sbill { 300*32Sbill register int s; 301*32Sbill 302*32Sbill if (p->c_cc <= 1) 303*32Sbill return(-1); 304*32Sbill s = getc(p); 305*32Sbill return(s | (getc(p)<<8)); 306*32Sbill } 307*32Sbill */ 308*32Sbill 309*32Sbill putw(c, p) 310*32Sbill register struct clist *p; 311*32Sbill { 312*32Sbill register s; 313*32Sbill 314*32Sbill s = spl6(); 315*32Sbill if (cfreelist==NULL) { 316*32Sbill splx(s); 317*32Sbill return(-1); 318*32Sbill } 319*32Sbill VOID putc(c, p); 320*32Sbill VOID putc(c>>8, p); 321*32Sbill splx(s); 322*32Sbill return(0); 323*32Sbill } 324