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

Defined functions

chksum defined in line 616; used 2 times
pkaccept defined in line 122; used 1 times
pkclose defined in line 524; used 1 times
pkcntl defined in line 39; used 1 times
pkline defined in line 643; never used
pkoutput defined in line 405; used 10 times
pkread defined in line 263; used 2 times
pkreset defined in line 608; used 1 times
pksack defined in line 382; used 2 times
pksize defined in line 662; used 1 times
pkwrite defined in line 326; used 1 times
pkzero defined in line 654; used 1 times

Defined variables

mask defined in line 23; used 9 times
next defined in line 22; used 17 times
pkactive defined in line 33; used 1 times
pkdebug defined in line 34; never used
pklines defined in line 25; used 3 times
sccsid defined in line 2; never used

Defined macros

USER defined in line 7; never used
Last modified: 1983-07-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1138
Valid CSS Valid XHTML 1.0 Strict