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

Defined functions

chksum defined in line 628; used 2 times
pkaccept defined in line 125; used 1 times
pkbadframe defined in line 109; used 4 times
pkclose defined in line 539; never used
pkcntl defined in line 18; used 1 times
pkline defined in line 656; never used
pkoutput defined in line 422; used 12 times
pkread defined in line 258; never used
pkreset defined in line 620; used 1 times
pksack defined in line 396; used 2 times
pksize defined in line 675; used 1 times
pkwrite defined in line 336; never used
pkzero defined in line 667; used 1 times

Defined variables

mask defined in line 9; used 4 times
next defined in line 8; used 8 times
pklines defined in line 11; used 3 times

Defined macros

KERNEL defined in line 1; never used
NTRIES defined in line 546; used 2 times
Last modified: 1979-05-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1135
Valid CSS Valid XHTML 1.0 Strict