1: #define KERNEL  1
   2: #include <sys/pk.p>
   3: 
   4: #ifdef  UCB_SCCSID
   5: static  char sccs_id[] = "@(#)pk0.c	3.1";
   6: #endif
   7: 
   8: 
   9: /*
  10:  * packet driver
  11:  */
  12: 
  13: char next[8]    ={ 1,2,3,4,5,6,7,0};    /* packet sequence numbers */
  14: char mask[8]    ={ 1,2,4,010,020,040,0100,0200 };
  15: 
  16: struct pack *pklines[NPLINES];
  17: 
  18: 
  19: /*
  20:  * receive control messages
  21:  */
  22: 
  23: pkcntl(cntl, pk)
  24: register cntl;
  25: register struct pack *pk;
  26: {
  27: register val;
  28: register m;
  29: 
  30:     val = cntl & MOD8;
  31: 
  32:     if ( NOTCNTL(cntl) ) {
  33:         pkbadframe(pk);
  34:         return;
  35:     }
  36: 
  37:     cntl >>= 3;
  38:     pk->p_state &= ~BADFRAME;
  39:     m = pk->p_msg;
  40: 
  41:     switch(cntl) {
  42: 
  43:     case INITB:
  44:         val++;
  45:         pk->p_xsize = pksizes[val];
  46:         pk->p_lpsize = val;
  47:         pk->p_bits = DTOM(pk->p_xsize);
  48:         if (pk->p_state & LIVE) {
  49:             pk->p_msg |= M_INITC;
  50:             break;
  51:         }
  52:         pk->p_state |= INITb;
  53:         if ((pk->p_state & INITa)==0) {
  54:             break;
  55:         }
  56:         pk->p_rmsg &= ~M_INITA;
  57:         pk->p_msg |= M_INITC;
  58:         break;
  59: 
  60:     case INITC:
  61:         if ((pk->p_state&INITab)==INITab) {
  62:             pk->p_state = LIVE;
  63:             WAKEUP(&pk->p_state);
  64:             pk->p_rmsg &= ~(M_INITA|M_INITB);
  65:         } else
  66:             if ((pk->p_state&LIVE)==0)
  67:                 pk->p_msg |= M_INITB;
  68:         if (val)
  69:             pk->p_swindow = val;
  70:         break;
  71:     case INITA:
  72:         if (val==0 && pk->p_state&LIVE) {
  73:             printf("alloc change\n");
  74:             break;
  75:         }
  76:         if (val) {
  77:             pk->p_state |= INITa;
  78:             pk->p_msg |= M_INITB;
  79:             pk->p_rmsg |= M_INITB;
  80:             pk->p_swindow = val;
  81:         }
  82:         break;
  83:     case RJ:
  84:         pk->p_state |= RXMIT;
  85:         pk->p_msg |= M_RR;
  86:     case RR:
  87:         pk->p_rpr = val;
  88:         if (pksack(pk)==0) {
  89:             WAKEUP(&pk->p_ps);
  90:         }
  91:         break;
  92:     case CLOSE:
  93:         pk->p_state = DOWN+RCLOSE;
  94:         pk->p_rmsg = 0;
  95:         WAKEUP(&pk->p_pr);
  96:         WAKEUP(&pk->p_ps);
  97:         WAKEUP(&pk->p_state);
  98:         return;
  99:     }
 100:     if (pk->p_msg==0)
 101:         pk->p_msg |= pk->p_rmsg;
 102: 
 103: 
 104:     if (m==0 && pk->p_msg)
 105:         pkoutput(pk);
 106: }
 107: 
 108: 
 109: /*
 110:  * Send RJ message on first framing error.
 111:  * Cleared by receiving a good frame
 112:  * (pkcntl or pkdata).
 113:  */
 114: pkbadframe(pk)
 115: register struct pack *pk;
 116: {
 117:     WAKEUP(&pk->p_pr);
 118:     if (pk->p_state & BADFRAME)
 119:         return;
 120:     pk->p_state |= BADFRAME;
 121:     pk->p_timer = 2;
 122: }
 123: 
 124: 
 125: 
 126: 
 127: /*
 128:  * Look at sequence numbers (mostly).
 129:  */
 130: pkaccept(pk)
 131: register struct pack *pk;
 132: {
 133: register x, seq;
 134: char m, cntl, *p, imask, **bp;
 135: int bad, accept, skip, s, t, cc;
 136: unsigned short sum;
 137: 
 138:     bad = accept = skip = 0;
 139:     /*
 140: 	 * wait for input
 141: 	 */
 142:     LOCK;
 143:     x = next[pk->p_pr];
 144:     if((imask=pk->p_imap)==0 && pk->p_rcount==0) {
 145:         UNLOCK;
 146:         goto out;
 147:     }
 148:     pk->p_imap = 0;
 149:     UNLOCK;
 150: 
 151: 
 152:     /*
 153: 	 * determine input window in m.
 154: 	 */
 155:     t = (~(-1<<pk->p_rwindow)) <<x;
 156:     m = t;
 157:     m |= t>>8;
 158: 
 159: 
 160:     /*
 161: 	 * mark newly accepted input buffers
 162: 	 */
 163:     for(x=0; x<8; x++) {
 164: 
 165:         if ((imask & mask[x]) == 0)
 166:             continue;
 167: 
 168:         if (((cntl=pk->p_is[x])&0200)==0) {
 169:             bad++;
 170: free:
 171:             bp = (char **)pk->p_ib[x];
 172:             LOCK;
 173:             *bp = (char *)pk->p_ipool;
 174:             pk->p_ipool = bp;
 175:             pk->p_is[x] = 0;
 176:             UNLOCK;
 177:             continue;
 178:         }
 179: 
 180:         pk->p_is[x] = ~(B_COPY+B_MARK);
 181:         sum = (unsigned)chksum(pk->p_ib[x], pk->p_rsize) ^ (unsigned)cntl;
 182:         sum += pk->p_isum[x];
 183:         if (sum == CHECK) {
 184:             seq = (cntl>>3) & MOD8;
 185:             if (m & mask[seq]) {
 186:                 if (pk->p_is[seq] & (B_COPY | B_MARK)) {
 187:                 dup:
 188:                     skip++;
 189:                     goto free;
 190:                 }
 191:                 if (x != seq) {
 192:                     LOCK;
 193:                     p = pk->p_ib[x];
 194:                     pk->p_ib[x] = pk->p_ib[seq];
 195:                     pk->p_is[x] = pk->p_is[seq];
 196:                     pk->p_ib[seq] = p;
 197:                     UNLOCK;
 198:                 }
 199:                 pk->p_is[seq] = B_MARK;
 200:                 accept++;
 201:                 cc = 0;
 202:                 if (cntl&B_SHORT) {
 203:                     pk->p_is[seq] = B_MARK+B_SHORT;
 204:                     p = pk->p_ib[seq];
 205:                     cc = (unsigned)*p++;
 206:                     if (cc & 0200) {
 207:                         cc &= 0177;
 208:                         cc |= *p << 7;
 209:                     }
 210:                 }
 211:                 pk->p_isum[seq] = pk->p_rsize - cc;
 212:             } else {
 213:                 goto dup;
 214:             }
 215:         } else {
 216:             bad++;
 217:             goto free;
 218:         }
 219:     }
 220: 
 221:     /*
 222: 	 * scan window again turning marked buffers into
 223: 	 * COPY buffers and looking for missing sequence
 224: 	 * numbers.
 225: 	 */
 226:     accept = 0;
 227:     for(x=next[pk->p_pr],t= -1; m & mask[x]; x = next[x]) {
 228:         if (pk->p_is[x] & B_MARK)
 229:             pk->p_is[x] |= B_COPY;
 230:         if (pk->p_is[x] & B_COPY) {
 231:             if (t >= 0) {
 232:                 bp = (char **)pk->p_ib[x];
 233:                 LOCK;
 234:                 *bp = (char *)pk->p_ipool;
 235:                 pk->p_ipool = bp;
 236:                 pk->p_is[x] = 0;
 237:                 UNLOCK;
 238:                 skip++;
 239:             } else
 240:                 accept++;
 241:         } else {
 242:             if (t<0)
 243:                 t = x;
 244:         }
 245:     }
 246: 
 247:     if (bad) {
 248:         pk->p_msg |= M_RJ;
 249:     } else
 250: 
 251:     if (skip) {
 252:         pk->p_msg |= M_RR;
 253:     }
 254: 
 255:     pk->p_rcount = accept;
 256: out:
 257:     if (pk->p_msg)
 258:         pkoutput(pk);
 259:     return(accept);
 260: }
 261: 
 262: 
 263: pkread(S)
 264: SDEF;
 265: {
 266: register struct pack *pk;
 267: register x,s;
 268: int is,cc,xfr,count;
 269: char *cp, **bp;
 270: 
 271:     pk = PADDR;
 272:     xfr = 0;
 273:     count = -1;
 274:     while (pkaccept(pk) == 0) {
 275:         PKGETPKT(pk);
 276:         if (pk->p_state&DOWN) {
 277:             SETERROR;
 278:             goto out;
 279:         }
 280:         if (SLEEPNO) {
 281:             count++;
 282:             goto out;
 283:         }
 284:         SLEEP(&pk->p_pr, PKIPRI);
 285:     }
 286:     count = 0;
 287: 
 288: 
 289:     while (UCOUNT) {
 290: 
 291:         x = next[pk->p_pr];
 292:         is = pk->p_is[x];
 293: 
 294:         if (is & B_COPY) {
 295:             cc = MIN(pk->p_isum[x], UCOUNT);
 296:             if (cc==0 && xfr) {
 297:                 break;
 298:             }
 299:             if (is & B_RESID)
 300:                 cp = pk->p_rptr;
 301:             else {
 302:                 cp = pk->p_ib[x];
 303:                 if (is & B_SHORT) {
 304:                     if (*cp++ & 0200)
 305:                         *cp++;
 306:                 }
 307:             }
 308:             IOMOVE(cp,cc,B_READ);
 309:             count += cc;
 310:             xfr++;
 311:             pk->p_isum[x] -= cc;
 312:             if (pk->p_isum[x] == 0) {
 313:                 LOCK;
 314:                 pk->p_pr = x;
 315:                 bp = (char **)pk->p_ib[x];
 316:                 *bp = (char *)pk->p_ipool;
 317:                 pk->p_ipool = bp;
 318:                 pk->p_is[x] = 0;
 319:                 pk->p_rcount--;
 320:                 UNLOCK;
 321:                 pk->p_msg |= M_RR;
 322:             } else {
 323:                 pk->p_rptr = cp+cc;
 324:                 pk->p_is[x] |= B_RESID;
 325:             }
 326:             if (cc==0)
 327:                 break;
 328:         } else
 329:             break;
 330:     }
 331:     pkoutput(pk);
 332:     if (SLEEPNO)
 333:         count = pk->p_rcount;
 334: out:
 335:     return(count);
 336: }
 337: 
 338: 
 339: 
 340: 
 341: pkwrite(S)
 342: SDEF;
 343: {
 344: register struct pack *pk;
 345: register x;
 346: int partial;
 347: caddr_t cp;
 348: int cc, s, fc, count;
 349: int pktimeout();
 350: 
 351:     pk = PADDR;
 352:     if ((pk->p_state&LIVE)==0) {
 353:     down:
 354:         SIGNAL;
 355:         SETERROR;
 356:         return(-1);
 357:     }
 358: 
 359:     count = UCOUNT;
 360:     do {
 361:         LOCK;
 362:         while (pk->p_xcount>=pk->p_swindow)  {
 363:             pkoutput(pk);
 364:             PKGETPKT(pk);
 365:             SLEEP(&pk->p_ps,PKOPRI);
 366:             if (pk->p_state&DOWN)
 367:                 goto down;
 368:         }
 369:         x = next[pk->p_pscopy];
 370:         while (pk->p_os[x]!=B_NULL)  {
 371:             goto down;
 372:         }
 373:         pk->p_os[x] = B_MARK;
 374:         pk->p_pscopy = x;
 375:         pk->p_xcount++;
 376:         UNLOCK;
 377: 
 378:         cp = pk->p_ob[x] = (char *)GETEPACK;
 379:         partial = 0;
 380:         if ((int)UCOUNT < pk->p_xsize) {
 381:             cc = UCOUNT;
 382:             fc = pk->p_xsize - cc;
 383:             *cp = fc&0177;
 384:             if (fc > 127) {
 385:                 *cp++ |= 0200;
 386:                 *cp++ = fc>>7;
 387:             } else
 388:                 cp++;
 389:             partial = B_SHORT;
 390:         } else
 391:             cc = pk->p_xsize;
 392:         IOMOVE(cp,cc,B_WRITE);
 393:         pk->p_osum[x] = chksum(pk->p_ob[x], pk->p_xsize);
 394:         pk->p_os[x] = B_READY+partial;
 395:         pkoutput(pk);
 396:     } while (UCOUNT);
 397: 
 398:     return(count-UCOUNT);
 399: }
 400: 
 401: pksack(pk)
 402: register struct pack *pk;
 403: {
 404: register x, i;
 405: int s;
 406: 
 407:     i = 0;
 408:     LOCK;
 409:     for(x=pk->p_ps; x!=pk->p_rpr; ) {
 410:         x = next[x];
 411:         if (pk->p_os[x]&B_SENT) {
 412:             i++;
 413:             FREEPACK(pk->p_ob[x], pk->p_bits);
 414:             pk->p_os[x] = B_NULL;
 415:             pk->p_state &= ~WAITO;
 416:             pk->p_xcount--;
 417:             pk->p_ps = x;
 418:             WAKEUP(&pk->p_ps);
 419:         }
 420:     }
 421:     UNLOCK;
 422:     return(i);
 423: }
 424: 
 425: 
 426: 
 427: pkoutput(pk)
 428: register struct pack *pk;
 429: {
 430: register x;
 431: int s;
 432: char bstate;
 433: int i;
 434: SDEF;
 435: extern pkzot;
 436: 
 437:     ISYSTEM;
 438:     LOCK;
 439:     if (OBUSY) {
 440:         UNLOCK;
 441:         return;
 442:     }
 443: 
 444: 
 445:     /*
 446: 	 * find seq number and buffer state
 447: 	 * of next output packet
 448: 	 */
 449:     if (pk->p_state&RXMIT)  {
 450:         pk->p_nxtps = next[pk->p_rpr];
 451:         pk->p_state &= ~RXMIT;
 452:     }
 453:     x = pk->p_nxtps;
 454:     bstate = pk->p_os[x];
 455: 
 456: 
 457:     /*
 458: 	 * Send control packet if indicated
 459: 	 */
 460:     if (pk->p_msg) {
 461:         if (pk->p_msg & ~M_RR || !(bstate&B_READY) ) {
 462:             x = pk->p_msg;
 463:             for(i=0; i<8; i++)
 464:                 if (x&1)
 465:                     break; else
 466:                 x >>= 1;
 467:             x = i;
 468:             x <<= 3;
 469:             switch(i) {
 470:             case CLOSE:
 471:                 break;
 472:             case RJ:
 473:             case RR:
 474:                 x += pk->p_pr;
 475:                 break;
 476:             case SRJ:
 477:                 break;
 478:             case INITB:
 479:                 x += pksize(pk->p_rsize);
 480:                 break;
 481:             case INITC:
 482:                 x += pk->p_rwindow;
 483:                 break;
 484:             case INITA:
 485:                 x += pk->p_rwindow;
 486:                 break;
 487:             }
 488: 
 489:             pk->p_msg &= ~mask[i];
 490:             pkxstart(pk, x, -1);
 491:             goto out;
 492:         }
 493:     }
 494: 
 495: 
 496:     /*
 497: 	 * Don't send data packets if line is marked dead.
 498: 	 */
 499:     if (pk->p_state&DOWN || (pk->p_state&LIVE)==0) {
 500:         WAKEUP(&pk->p_ps);
 501:         goto out;
 502:     }
 503:     /*
 504: 	 * Start transmission (or retransmission) of data packets.
 505: 	 */
 506:     if (bstate & (B_READY|B_SENT)) {
 507:         char seq;
 508: 
 509:         bstate |= B_SENT;
 510:         seq = x;
 511:         pk->p_nxtps = next[x];
 512: 
 513:         x = 0200+pk->p_pr+(seq<<3);
 514:         if (bstate & B_SHORT)
 515:             x |= 0100;
 516:         pkxstart(pk, x, seq);
 517:         if (pk->p_os[seq])
 518:             pk->p_os[seq] = bstate;
 519:         pk->p_nout++;
 520:         goto out;
 521:     }
 522:     /*
 523: 	 * enable timeout if there's nothing to send
 524: 	 * and transmission buffers are languishing
 525: 	 */
 526:     if (pk->p_xcount) {
 527:         pk->p_timer = 10+pkzot;
 528:         pk->p_state |= WAITO;
 529:     } else
 530:         pk->p_state &= ~WAITO;
 531:     WAKEUP(&pk->p_ps);
 532: out:
 533:     pk->p_obusy = 0;
 534:     UNLOCK;
 535: }
 536: 
 537: 
 538: /*
 539:  * shut down line by
 540:  *	ignoring new input
 541:  *	letting output drain
 542:  *	releasing space and turning off line discipline
 543:  */
 544: pkclose(S)
 545: SDEF;
 546: {
 547: register struct pack *pk;
 548: register i,s,rbits;
 549: char **bp;
 550: 
 551: #define NTRIES  1
 552: 
 553:     pk = PADDR;
 554:     pk->p_state |= DRAINO;
 555: 
 556: 
 557:     /*
 558: 	 * try to flush output
 559: 	 */
 560:     i = 0;
 561:     LOCK;
 562:     if (pklive(pk)==0) {
 563:         pk->p_state = DOWN;
 564:         UNLOCK;
 565:         goto final;
 566:     }
 567:     pk->p_timer = 2;
 568:     while (pk->p_xcount && pk->p_state&LIVE) {
 569:         if (pk->p_state&(RCLOSE+DOWN) || ++i > NTRIES)
 570:             break;
 571:         pkoutput(pk);
 572:         SLEEP(&pk->p_ps,PKOPRI);
 573:     }
 574:     pk->p_timer = 0;
 575:     pk->p_state |= DOWN;
 576:     UNLOCK;
 577: 
 578: 
 579:     /*
 580: 	 * try to exchange CLOSE messages
 581: 	 */
 582:     i = 0;
 583:     while ((pk->p_state&RCLOSE)==0 && i<NTRIES) {
 584:         pk->p_msg = M_CLOSE;
 585:         pk->p_timer = 2;
 586:         pkoutput(pk);
 587:         SLEEP(&pk->p_ps, PKOPRI);
 588:         i++;
 589:     }
 590: 
 591: 
 592: final:
 593:     TURNOFF;
 594: 
 595: 
 596:     /*
 597: 	 * free space
 598: 	 */
 599:     rbits = DTOM(pk->p_rsize);
 600:     for (i=0;i<8;i++) {
 601:         if (pk->p_os[i]!=B_NULL) {
 602:             FREEPACK(pk->p_ob[i],pk->p_bits);
 603:             pk->p_xcount--;
 604:         }
 605:         if (pk->p_is[i]!=B_NULL)  {
 606:             FREEPACK(pk->p_ib[i],rbits);
 607:         }
 608:     }
 609:     LOCK;
 610:     while (pk->p_ipool != NULL) {
 611:         bp = pk->p_ipool;
 612:         pk->p_ipool = (char **)*bp;
 613:         FREEPACK((caddr_t)bp, rbits);
 614:     }
 615:     UNLOCK;
 616:     for(i=0;i<NPLINES;i++)
 617:         if (pklines[i]==pk)  {
 618:             pklines[i] = NULL;
 619:         }
 620:     FREEPACK((caddr_t)pk, npbits);
 621: }
 622: 
 623: 
 624: 
 625: pkreset(pk)
 626: register struct pack *pk;
 627: {
 628: 
 629:     pk->p_ps = pk->p_pr =  pk->p_rpr = 0;
 630:     pk->p_nxtps = 1;
 631: }
 632: 
 633: chksum(s,n)
 634: register char *s;
 635: register n;
 636: {
 637:     register short sum;
 638:     register unsigned t;
 639:     register x;
 640: 
 641:     sum = -1;
 642:     x = 0;
 643: 
 644:     do {
 645:         if (sum<0) {
 646:             sum <<= 1;
 647:             sum++;
 648:         } else
 649:             sum <<= 1;
 650:         t = sum;
 651:         sum += (unsigned)*s++;
 652:         x += sum^n;
 653:         if ((unsigned)sum <= t) {
 654:             sum ^= x;
 655:         }
 656:     } while (--n > 0);
 657: 
 658:     return(sum);
 659: }
 660: 
 661: pkline(pk)
 662: register struct pack *pk;
 663: {
 664: register i;
 665:     for(i=0;i<NPLINES;i++) {
 666:         if (pklines[i]==pk)
 667:             return(i);
 668:     }
 669:     return(-i);
 670: }
 671: 
 672: pkzero(s,n)
 673: register char *s;
 674: register n;
 675: {
 676:     while (n--)
 677:         *s++ = 0;
 678: }
 679: 
 680: pksize(n)
 681: register n;
 682: {
 683: register k;
 684: 
 685:     n >>= 5;
 686:     for(k=0; n >>= 1; k++);
 687:     return(k);
 688: }

Defined functions

chksum defined in line 633; used 2 times
pkaccept defined in line 130; used 1 times
pkbadframe defined in line 114; used 4 times
pkclose defined in line 544; never used
pkcntl defined in line 23; used 1 times
pkline defined in line 661; never used
pkoutput defined in line 427; used 12 times
pkread defined in line 263; never used
pkreset defined in line 625; used 1 times
pksack defined in line 401; used 2 times
pksize defined in line 680; used 1 times
pkwrite defined in line 341; never used
pkzero defined in line 672; used 1 times

Defined variables

mask defined in line 14; used 4 times
next defined in line 13; used 8 times
pklines defined in line 16; used 3 times
sccs_id defined in line 5; never used

Defined macros

KERNEL defined in line 1; never used
NTRIES defined in line 551; used 2 times
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1014
Valid CSS Valid XHTML 1.0 Strict