1: /*
   2:  * Copyright (c) 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	1.1 (2.10BSD Berkeley) 12/1/86
   7:  */
   8: 
   9: #include "param.h"
  10: #include "../machine/seg.h"
  11: #include "clist.h"
  12: #include "ioctl.h"
  13: #include "tty.h"
  14: 
  15: #ifdef UCB_CLIST
  16: /*
  17:  *  Modification to move clists out of kernel data space.
  18:  *  Clist space is allocated by startup.
  19:  */
  20: memaddr clststrt;       /* physical click address of clist */
  21: struct  cblock *cfree = (struct cblock *)SEG5;
  22: #endif
  23: 
  24: char    cwaiting;
  25: 
  26: /*
  27:  * Character list get/put
  28:  */
  29: getc(p)
  30:     register struct clist *p;
  31: {
  32:     register struct cblock *bp;
  33:     register int c, s;
  34: #ifdef UCB_CLIST
  35:     segm sav5;
  36: #endif
  37: 
  38:     s = spltty();
  39: #ifdef UCB_CLIST
  40:     saveseg5(sav5);
  41:     mapseg5(clststrt, clstdesc);
  42: #endif
  43:     if (p->c_cc <= 0) {
  44:         c = -1;
  45:         p->c_cc = 0;
  46:         p->c_cf = p->c_cl = NULL;
  47:     } else {
  48:         c = *p->c_cf++ & 0377;
  49:         if (--p->c_cc<=0) {
  50:             bp = (struct cblock *)(p->c_cf-1);
  51:             bp = (struct cblock *)((int)bp & ~CROUND);
  52:             p->c_cf = NULL;
  53:             p->c_cl = NULL;
  54:             bp->c_next = cfreelist;
  55:             cfreelist = bp;
  56:             cfreecount += CBSIZE;
  57:             if (cwaiting) {
  58:                 wakeup(&cwaiting);
  59:                 cwaiting = 0;
  60:             }
  61:         } else if (((int)p->c_cf & CROUND) == 0){
  62:             bp = (struct cblock *)(p->c_cf);
  63:             bp--;
  64:             p->c_cf = bp->c_next->c_info;
  65:             bp->c_next = cfreelist;
  66:             cfreelist = bp;
  67:             cfreecount += CBSIZE;
  68:             if (cwaiting) {
  69:                 wakeup(&cwaiting);
  70:                 cwaiting = 0;
  71:             }
  72:         }
  73:     }
  74: #ifdef UCB_CLIST
  75:     restorseg5(sav5);
  76: #endif
  77:     splx(s);
  78:     return (c);
  79: }
  80: 
  81: /*
  82:  * copy clist to buffer.
  83:  * return number of bytes moved.
  84:  */
  85: q_to_b(q, cp, cc)
  86:     register struct clist *q;
  87:     char *cp;
  88: {
  89:     register struct cblock *bp;
  90:     register nc;
  91:     int s;
  92:     char *acp;
  93: #ifdef UCB_CLIST
  94:     segm sav5;
  95: #endif
  96: 
  97:     if (cc <= 0)
  98:         return (0);
  99:     s = spltty();
 100: #ifdef UCB_CLIST
 101:     saveseg5(sav5);
 102:     mapseg5(clststrt, clstdesc);
 103: #endif
 104:     if (q->c_cc <= 0) {
 105:         q->c_cc = 0;
 106:         q->c_cf = q->c_cl = NULL;
 107: #ifdef UCB_CLIST
 108:         restorseg5(sav5);
 109: #endif
 110:         splx(s);
 111:         return (0);
 112:     }
 113:     acp = cp;
 114: 
 115:     while (cc) {
 116:         nc = sizeof (struct cblock) - ((int)q->c_cf & CROUND);
 117:         nc = MIN(nc, cc);
 118:         nc = MIN(nc, q->c_cc);
 119:         (void) bcopy(q->c_cf, cp, (unsigned)nc);
 120:         q->c_cf += nc;
 121:         q->c_cc -= nc;
 122:         cc -= nc;
 123:         cp += nc;
 124:         if (q->c_cc <= 0) {
 125:             bp = (struct cblock *)(q->c_cf - 1);
 126:             bp = (struct cblock *)((int)bp & ~CROUND);
 127:             q->c_cf = q->c_cl = NULL;
 128:             bp->c_next = cfreelist;
 129:             cfreelist = bp;
 130:             cfreecount += CBSIZE;
 131:             if (cwaiting) {
 132:                 wakeup(&cwaiting);
 133:                 cwaiting = 0;
 134:             }
 135:             break;
 136:         }
 137:         if (((int)q->c_cf & CROUND) == 0) {
 138:             bp = (struct cblock *)(q->c_cf);
 139:             bp--;
 140:             q->c_cf = bp->c_next->c_info;
 141:             bp->c_next = cfreelist;
 142:             cfreelist = bp;
 143:             cfreecount += CBSIZE;
 144:             if (cwaiting) {
 145:                 wakeup(&cwaiting);
 146:                 cwaiting = 0;
 147:             }
 148:         }
 149:     }
 150: #ifdef UCB_CLIST
 151:     restorseg5(sav5);
 152: #endif
 153:     splx(s);
 154:     return (cp-acp);
 155: }
 156: 
 157: /*
 158:  * Return count of contiguous characters
 159:  * in clist starting at q->c_cf.
 160:  * Stop counting if flag&character is non-null.
 161:  */
 162: ndqb(q, flag)
 163:     register struct clist *q;
 164: {
 165:     int cc;
 166:     int s;
 167: #ifdef UCB_CLIST
 168:     segm sav5;
 169: #endif
 170: 
 171:     s = spltty();
 172:     if (q->c_cc <= 0) {
 173:         cc = -q->c_cc;
 174:         goto out;
 175:     }
 176:     cc = ((int)q->c_cf + CBSIZE) & ~CROUND;
 177:     cc -= (int)q->c_cf;
 178:     if (q->c_cc < cc)
 179:         cc = q->c_cc;
 180:     if (flag) {
 181:         register char *p, *end;
 182: 
 183: #ifdef UCB_CLIST
 184:         saveseg5(sav5);
 185:         mapseg5(clststrt, clstdesc);
 186: #endif
 187:         p = q->c_cf;
 188:         end = p;
 189:         end += cc;
 190:         while (p < end) {
 191:             if (*p & flag) {
 192:                 cc = (int)p;
 193:                 cc -= (int)q->c_cf;
 194:                 break;
 195:             }
 196:             p++;
 197:         }
 198: #ifdef UCB_CLIST
 199:         restorseg5(sav5);
 200: #endif
 201:     }
 202: out:
 203:     splx(s);
 204:     return (cc);
 205: }
 206: 
 207: /*
 208:  * Flush cc bytes from q.
 209:  */
 210: ndflush(q, cc)
 211:     register struct clist *q;
 212:     register cc;
 213: {
 214:     register struct cblock *bp;
 215:     char *end;
 216:     int rem, s;
 217: #ifdef UCB_CLIST
 218:     segm sav5;
 219: #endif
 220: 
 221:     s = spltty();
 222:     if (q->c_cc <= 0)
 223:         goto out;
 224: #ifdef UCB_CLIST
 225:     saveseg5(sav5);
 226:     mapseg5(clststrt, clstdesc);
 227: #endif
 228:     while (cc>0 && q->c_cc) {
 229:         bp = (struct cblock *)((int)q->c_cf & ~CROUND);
 230:         if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
 231:             end = q->c_cl;
 232:         } else {
 233:             end = (char *)((int)bp + sizeof (struct cblock));
 234:         }
 235:         rem = end - q->c_cf;
 236:         if (cc >= rem) {
 237:             cc -= rem;
 238:             q->c_cc -= rem;
 239:             q->c_cf = bp->c_next->c_info;
 240:             bp->c_next = cfreelist;
 241:             cfreelist = bp;
 242:             cfreecount += CBSIZE;
 243:             if (cwaiting) {
 244:                 wakeup(&cwaiting);
 245:                 cwaiting = 0;
 246:             }
 247:         } else {
 248:             q->c_cc -= cc;
 249:             q->c_cf += cc;
 250:             if (q->c_cc <= 0) {
 251:                 bp->c_next = cfreelist;
 252:                 cfreelist = bp;
 253:                 cfreecount += CBSIZE;
 254:                 if (cwaiting) {
 255:                     wakeup(&cwaiting);
 256:                     cwaiting = 0;
 257:                 }
 258:             }
 259:             break;
 260:         }
 261:     }
 262: #ifdef UCB_CLIST
 263:     restorseg5(sav5);
 264: #endif
 265:     if (q->c_cc <= 0) {
 266:         q->c_cf = q->c_cl = NULL;
 267:         q->c_cc = 0;
 268:     }
 269: out:
 270:     splx(s);
 271: }
 272: 
 273: putc(c, p)
 274:     register struct clist *p;
 275: {
 276:     register struct cblock *bp;
 277:     register char *cp;
 278:     register s;
 279: #ifdef UCB_CLIST
 280:     segm sav5;
 281: #endif
 282: 
 283:     s = spltty();
 284: #ifdef UCB_CLIST
 285:     saveseg5(sav5);
 286:     mapseg5(clststrt, clstdesc);
 287: #endif
 288:     if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
 289:         if ((bp = cfreelist) == NULL) {
 290:             splx(s);
 291: #ifdef UCB_CLIST
 292:             restorseg5(sav5);
 293: #endif
 294:             return (-1);
 295:         }
 296:         cfreelist = bp->c_next;
 297:         cfreecount -= CBSIZE;
 298:         bp->c_next = NULL;
 299:         p->c_cf = cp = bp->c_info;
 300:     } else if (((int)cp & CROUND) == 0) {
 301:         bp = (struct cblock *)cp - 1;
 302:         if ((bp->c_next = cfreelist) == NULL) {
 303:             splx(s);
 304: #ifdef UCB_CLIST
 305:             restorseg5(sav5);
 306: #endif
 307:             return (-1);
 308:         }
 309:         bp = bp->c_next;
 310:         cfreelist = bp->c_next;
 311:         cfreecount -= CBSIZE;
 312:         bp->c_next = NULL;
 313:         cp = bp->c_info;
 314:     }
 315:     *cp++ = c;
 316:     p->c_cc++;
 317:     p->c_cl = cp;
 318: #ifdef UCB_CLIST
 319:     restorseg5(sav5);
 320: #endif
 321:     splx(s);
 322:     return (0);
 323: }
 324: 
 325: /*
 326:  * copy buffer to clist.
 327:  * return number of bytes not transfered.
 328:  */
 329: b_to_q(cp, cc, q)
 330:     register char *cp;
 331:     struct clist *q;
 332:     register int cc;
 333: {
 334:     register char *cq;
 335:     register struct cblock *bp;
 336:     register s, nc;
 337:     int acc;
 338: #ifdef UCB_CLIST
 339:     segm sav5;
 340: #endif
 341: 
 342:     if (cc <= 0)
 343:         return (0);
 344:     acc = cc;
 345:     s = spltty();
 346: #ifdef UCB_CLIST
 347:     saveseg5(sav5);
 348:     mapseg5(clststrt, clstdesc);
 349: #endif
 350:     if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
 351:         if ((bp = cfreelist) == NULL)
 352:             goto out;
 353:         cfreelist = bp->c_next;
 354:         cfreecount -= CBSIZE;
 355:         bp->c_next = NULL;
 356:         q->c_cf = cq = bp->c_info;
 357:     }
 358: 
 359:     while (cc) {
 360:         if (((int)cq & CROUND) == 0) {
 361:             bp = (struct cblock *)cq - 1;
 362:             if ((bp->c_next = cfreelist) == NULL)
 363:                 goto out;
 364:             bp = bp->c_next;
 365:             cfreelist = bp->c_next;
 366:             cfreecount -= CBSIZE;
 367:             bp->c_next = NULL;
 368:             cq = bp->c_info;
 369:         }
 370:         nc = MIN(cc, sizeof (struct cblock) - ((int)cq & CROUND));
 371:         (void) bcopy(cp, cq, (unsigned)nc);
 372:         cp += nc;
 373:         cq += nc;
 374:         cc -= nc;
 375:     }
 376: out:
 377:     q->c_cl = cq;
 378:     q->c_cc += acc - cc;
 379: #ifdef UCB_CLIST
 380:     restorseg5(sav5);
 381: #endif
 382:     splx(s);
 383:     return (cc);
 384: }
 385: 
 386: /*
 387:  * Given a non-NULL pointter into the list (like c_cf which
 388:  * always points to a real character if non-NULL) return the pointer
 389:  * to the next character in the list or return NULL if no more chars.
 390:  *
 391:  * Callers must not allow getc's to happen between nextc's so that the
 392:  * pointer becomes invalid.  Note that interrupts are NOT masked.
 393:  */
 394: char *
 395: #ifdef UCB_CLIST
 396: nextc(p, cp, store)
 397:     register struct clist *p;
 398:     register char *cp;
 399:     char *store;
 400: {
 401:     register char *rcp;
 402:     segm sav5;
 403: 
 404:     saveseg5(sav5);
 405:     mapseg5(clststrt, clstdesc);
 406: #else
 407: nextc(p, cp)
 408:     register struct clist *p;
 409:     register char *cp;
 410: {
 411:     register char *rcp;
 412: #endif
 413: 
 414:     if (p->c_cc && ++cp != p->c_cl) {
 415:         if (((int)cp & CROUND) == 0)
 416:             rcp = ((struct cblock *)cp)[-1].c_next->c_info;
 417:         else
 418:             rcp = cp;
 419: #ifdef UCB_CLIST
 420:         *store = *rcp;
 421: #endif
 422:     }
 423:     else
 424:         rcp = (char *)NULL;
 425: #ifdef UCB_CLIST
 426:     restorseg5(sav5);
 427: #endif
 428:     return (rcp);
 429: }
 430: 
 431: #ifdef UCB_CLIST
 432: char
 433: lookc(cp)
 434:     char *cp;
 435: {
 436:     register char rc;
 437:     segm sav5;
 438: 
 439:     saveseg5(sav5);
 440:     mapseg5(clststrt, clstdesc);
 441:     rc = *cp;
 442:     restorseg5(sav5);
 443:     return(rc);
 444: }
 445: #endif
 446: 
 447: /*
 448:  * Remove the last character in the list and return it.
 449:  */
 450: unputc(p)
 451:     register struct clist *p;
 452: {
 453:     register struct cblock *bp;
 454:     register int c, s;
 455:     struct cblock *obp;
 456: #ifdef UCB_CLIST
 457:     segm sav5;
 458: #endif
 459: 
 460:     s = spltty();
 461: #ifdef UCB_CLIST
 462:     saveseg5(sav5);
 463:     mapseg5(clststrt, clstdesc);
 464: #endif
 465:     if (p->c_cc <= 0)
 466:         c = -1;
 467:     else {
 468:         c = *--p->c_cl;
 469:         if (--p->c_cc <= 0) {
 470:             bp = (struct cblock *)p->c_cl;
 471:             bp = (struct cblock *)((int)bp & ~CROUND);
 472:             p->c_cl = p->c_cf = NULL;
 473:             bp->c_next = cfreelist;
 474:             cfreelist = bp;
 475:             cfreecount += CBSIZE;
 476:         } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) {
 477:             p->c_cl = (char *)((int)p->c_cl & ~CROUND);
 478:             bp = (struct cblock *)p->c_cf;
 479:             bp = (struct cblock *)((int)bp & ~CROUND);
 480:             while (bp->c_next != (struct cblock *)p->c_cl)
 481:                 bp = bp->c_next;
 482:             obp = bp;
 483:             p->c_cl = (char *)(bp + 1);
 484:             bp = bp->c_next;
 485:             bp->c_next = cfreelist;
 486:             cfreelist = bp;
 487:             cfreecount += CBSIZE;
 488:             obp->c_next = NULL;
 489:         }
 490:     }
 491: #ifdef UCB_CLIST
 492:     restorseg5(sav5);
 493: #endif
 494:     splx(s);
 495:     return (c);
 496: }
 497: 
 498: /*
 499:  * Put the chars in the from que
 500:  * on the end of the to que.
 501:  */
 502: catq(from, to)
 503:     register struct clist *from, *to;
 504: {
 505:     char bbuf[CBSIZE*4];
 506:     register c;
 507:     int s;
 508: 
 509:     s = spltty();
 510:     if (to->c_cc == 0) {
 511:         *to = *from;
 512:         from->c_cc = 0;
 513:         from->c_cf = NULL;
 514:         from->c_cl = NULL;
 515:         splx(s);
 516:         return;
 517:     }
 518:     splx(s);
 519:     while (from->c_cc > 0) {
 520:         c = q_to_b(from, bbuf, sizeof bbuf);
 521:         (void) b_to_q(bbuf, c, to);
 522:     }
 523: }
 524: 
 525: #ifdef unneeded
 526: /*
 527:  * Integer (short) get/put using clists.
 528:  * Note dependency on byte order.
 529:  */
 530: typedef u_short word_t;
 531: 
 532: getw(p)
 533:     register struct clist *p;
 534: {
 535:     register int s, c;
 536:     register struct cblock *bp;
 537: 
 538:     if (p->c_cc <= 1)
 539:         return(-1);
 540:     if (p->c_cc & 01) {
 541:         c = getc(p);
 542: #if defined(vax)
 543:         return (c | (getc(p)<<8));
 544: #else
 545:         return (getc(p) | (c<<8));
 546: #endif
 547:     }
 548:     s = spltty();
 549: #if defined(vax)
 550:     c = *((word_t *)p->c_cf);
 551: #else
 552:     c = (((u_char *)p->c_cf)[1] << 8) | ((u_char *)p->c_cf)[0];
 553: #endif
 554:     p->c_cf += sizeof (word_t);
 555:     p->c_cc -= sizeof (word_t);
 556:     if (p->c_cc <= 0) {
 557:         bp = (struct cblock *)(p->c_cf-1);
 558:         bp = (struct cblock *)((int)bp & ~CROUND);
 559:         p->c_cf = NULL;
 560:         p->c_cl = NULL;
 561:         bp->c_next = cfreelist;
 562:         cfreelist = bp;
 563:         cfreecount += CBSIZE;
 564:         if (cwaiting) {
 565:             wakeup(&cwaiting);
 566:             cwaiting = 0;
 567:         }
 568:     } else if (((int)p->c_cf & CROUND) == 0) {
 569:         bp = (struct cblock *)(p->c_cf);
 570:         bp--;
 571:         p->c_cf = bp->c_next->c_info;
 572:         bp->c_next = cfreelist;
 573:         cfreelist = bp;
 574:         cfreecount += CBSIZE;
 575:         if (cwaiting) {
 576:             wakeup(&cwaiting);
 577:             cwaiting = 0;
 578:         }
 579:     }
 580:     splx(s);
 581:     return (c);
 582: }
 583: 
 584: putw(c, p)
 585:     register struct clist *p;
 586:     word_t c;
 587: {
 588:     register s;
 589:     register struct cblock *bp;
 590:     register char *cp;
 591: 
 592:     s = spltty();
 593:     if (cfreelist==NULL) {
 594:         splx(s);
 595:         return(-1);
 596:     }
 597:     if (p->c_cc & 01) {
 598: #if defined(vax)
 599:         (void) putc(c, p);
 600:         (void) putc(c>>8, p);
 601: #else
 602:         (void) putc(c>>8, p);
 603:         (void) putc(c, p);
 604: #endif
 605:     } else {
 606:         if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
 607:             if ((bp = cfreelist) == NULL) {
 608:                 splx(s);
 609:                 return (-1);
 610:             }
 611:             cfreelist = bp->c_next;
 612:             cfreecount -= CBSIZE;
 613:             bp->c_next = NULL;
 614:             p->c_cf = cp = bp->c_info;
 615:         } else if (((int)cp & CROUND) == 0) {
 616:             bp = (struct cblock *)cp - 1;
 617:             if ((bp->c_next = cfreelist) == NULL) {
 618:                 splx(s);
 619:                 return (-1);
 620:             }
 621:             bp = bp->c_next;
 622:             cfreelist = bp->c_next;
 623:             cfreecount -= CBSIZE;
 624:             bp->c_next = NULL;
 625:             cp = bp->c_info;
 626:         }
 627: #if defined(vax)
 628:         *(word_t *)cp = c;
 629: #else
 630:         ((u_char *)cp)[0] = c>>8;
 631:         ((u_char *)cp)[1] = c;
 632: #endif
 633:         p->c_cl = cp + sizeof (word_t);
 634:         p->c_cc += sizeof (word_t);
 635:     }
 636:     splx(s);
 637:     return (0);
 638: }
 639: #endif unneeded

Defined functions

b_to_q defined in line 329; used 6 times
catq defined in line 502; used 2 times
getw defined in line 532; used 2 times
lookc defined in line 432; used 3 times
nextc defined in line 407; used 7 times
putw defined in line 584; used 2 times
q_to_b defined in line 85; used 2 times
unputc defined in line 450; used 6 times

Defined variables

clststrt defined in line 20; used 10 times
cwaiting defined in line 24; used 24 times

Defined typedef's

word_t defined in line 530; used 7 times
Last modified: 1987-08-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5098
Valid CSS Valid XHTML 1.0 Strict