1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1988 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include "uucp.h" 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include "pk.h" 36*7c478bd9Sstevel@tonic-gate #include <sys/buf.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate extern void pkcntl(), pkoutput(), pkclose(), pkreset(), pkzero(), 39*7c478bd9Sstevel@tonic-gate pkgetpack(), pkxstart(); 40*7c478bd9Sstevel@tonic-gate extern int pkread(), pkwrite(), pksack(); 41*7c478bd9Sstevel@tonic-gate static int pksize(), chksum(), pkaccept(); 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate extern int Connodata; /* Continuous No Valid Data Count */ 44*7c478bd9Sstevel@tonic-gate extern int xpacksize; 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* 47*7c478bd9Sstevel@tonic-gate * receive control messages 48*7c478bd9Sstevel@tonic-gate * c -> message type fields 49*7c478bd9Sstevel@tonic-gate * pk -> line control unit 50*7c478bd9Sstevel@tonic-gate */ 51*7c478bd9Sstevel@tonic-gate void 52*7c478bd9Sstevel@tonic-gate pkcntl(c, pk) 53*7c478bd9Sstevel@tonic-gate register struct pack *pk; 54*7c478bd9Sstevel@tonic-gate { 55*7c478bd9Sstevel@tonic-gate register cntl, val; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate val = c & MOD8; 58*7c478bd9Sstevel@tonic-gate cntl = (c>>3) & MOD8; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate if ( ! ISCNTL(c) ) { 61*7c478bd9Sstevel@tonic-gate logent("PK0", "not cntl"); 62*7c478bd9Sstevel@tonic-gate return; 63*7c478bd9Sstevel@tonic-gate } 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate if (Debug >= 9) 66*7c478bd9Sstevel@tonic-gate xlatecntl(0, c); 67*7c478bd9Sstevel@tonic-gate switch(cntl) { 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate case INITB: 70*7c478bd9Sstevel@tonic-gate val++; 71*7c478bd9Sstevel@tonic-gate pk->p_xsize = xpacksize = pksizes[val]; 72*7c478bd9Sstevel@tonic-gate pk->p_lpsize = val; 73*7c478bd9Sstevel@tonic-gate pk->p_bits = 1; 74*7c478bd9Sstevel@tonic-gate if (pk->p_state & LIVE) { 75*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_INITC; 76*7c478bd9Sstevel@tonic-gate break; 77*7c478bd9Sstevel@tonic-gate } 78*7c478bd9Sstevel@tonic-gate pk->p_state |= INITb; 79*7c478bd9Sstevel@tonic-gate if ((pk->p_state & INITa)==0) { 80*7c478bd9Sstevel@tonic-gate break; 81*7c478bd9Sstevel@tonic-gate } 82*7c478bd9Sstevel@tonic-gate pk->p_rmsg &= ~M_INITA; 83*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_INITC; 84*7c478bd9Sstevel@tonic-gate break; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate case INITC: 87*7c478bd9Sstevel@tonic-gate if ((pk->p_state&INITab)==INITab) { 88*7c478bd9Sstevel@tonic-gate pk->p_state = LIVE; 89*7c478bd9Sstevel@tonic-gate pk->p_rmsg &= ~M_INITB; 90*7c478bd9Sstevel@tonic-gate } else 91*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_INITB; 92*7c478bd9Sstevel@tonic-gate if (val) 93*7c478bd9Sstevel@tonic-gate pk->p_swindow = val; 94*7c478bd9Sstevel@tonic-gate break; 95*7c478bd9Sstevel@tonic-gate case INITA: 96*7c478bd9Sstevel@tonic-gate if (val==0 && pk->p_state&LIVE) { 97*7c478bd9Sstevel@tonic-gate logent("PK0", "alloc change not implemented"); 98*7c478bd9Sstevel@tonic-gate break; 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate if (val) { 101*7c478bd9Sstevel@tonic-gate pk->p_state |= INITa; 102*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_INITB; 103*7c478bd9Sstevel@tonic-gate pk->p_rmsg |= M_INITB; 104*7c478bd9Sstevel@tonic-gate pk->p_swindow = val; 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate break; 107*7c478bd9Sstevel@tonic-gate case RJ: 108*7c478bd9Sstevel@tonic-gate pk->p_state |= RXMIT; 109*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_RR; 110*7c478bd9Sstevel@tonic-gate DEBUG(9, "pkcntl: RJ: Connodata=%d\n", Connodata); 111*7c478bd9Sstevel@tonic-gate /* FALLTHRU */ 112*7c478bd9Sstevel@tonic-gate case RR: 113*7c478bd9Sstevel@tonic-gate pk->p_rpr = val; 114*7c478bd9Sstevel@tonic-gate (void) pksack(pk); 115*7c478bd9Sstevel@tonic-gate break; 116*7c478bd9Sstevel@tonic-gate case CLOSE: 117*7c478bd9Sstevel@tonic-gate pk->p_state = DOWN+RCLOSE; 118*7c478bd9Sstevel@tonic-gate return; 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate if (pk->p_msg) 121*7c478bd9Sstevel@tonic-gate pkoutput(pk); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate static int 125*7c478bd9Sstevel@tonic-gate pkaccept() 126*7c478bd9Sstevel@tonic-gate { 127*7c478bd9Sstevel@tonic-gate register struct pack *pk; 128*7c478bd9Sstevel@tonic-gate register x,seq; 129*7c478bd9Sstevel@tonic-gate char m, cntl, *p, imask, **bp; 130*7c478bd9Sstevel@tonic-gate int bad,accept,skip,t,cc; 131*7c478bd9Sstevel@tonic-gate unsigned short sum; 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate pk = Pk; 134*7c478bd9Sstevel@tonic-gate bad = accept = skip = 0; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate /* 137*7c478bd9Sstevel@tonic-gate * wait for input 138*7c478bd9Sstevel@tonic-gate */ 139*7c478bd9Sstevel@tonic-gate x = next[pk->p_pr]; 140*7c478bd9Sstevel@tonic-gate while ((imask=pk->p_imap) == 0 && pk->p_rcount==0) { 141*7c478bd9Sstevel@tonic-gate pkgetpack(pk); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate pk->p_imap = 0; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate /* 147*7c478bd9Sstevel@tonic-gate * determine input window in m. 148*7c478bd9Sstevel@tonic-gate */ 149*7c478bd9Sstevel@tonic-gate t = (~(-1<<pk->p_rwindow)) <<x; 150*7c478bd9Sstevel@tonic-gate m = t; 151*7c478bd9Sstevel@tonic-gate m |= t>>8; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate /* 155*7c478bd9Sstevel@tonic-gate * mark newly accepted input buffers 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate for(x=0; x<8; x++) { 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate if ((imask & mask[x]) == 0) 160*7c478bd9Sstevel@tonic-gate continue; 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate if (((cntl=pk->p_is[x])&0200)==0) { 163*7c478bd9Sstevel@tonic-gate bad++; 164*7c478bd9Sstevel@tonic-gate free: 165*7c478bd9Sstevel@tonic-gate bp = (char **)pk->p_ib[x]; 166*7c478bd9Sstevel@tonic-gate *bp = (char *)pk->p_ipool; 167*7c478bd9Sstevel@tonic-gate pk->p_ipool = bp; 168*7c478bd9Sstevel@tonic-gate pk->p_is[x] = 0; 169*7c478bd9Sstevel@tonic-gate continue; 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate pk->p_is[x] = (char) ~(B_COPY+B_MARK); 173*7c478bd9Sstevel@tonic-gate sum = (unsigned)chksum(pk->p_ib[x], pk->p_rsize) ^ (unsigned)(cntl&0377); 174*7c478bd9Sstevel@tonic-gate sum += pk->p_isum[x]; 175*7c478bd9Sstevel@tonic-gate if (sum == CHECK) { 176*7c478bd9Sstevel@tonic-gate seq = (cntl>>3) & MOD8; 177*7c478bd9Sstevel@tonic-gate if (m & mask[seq]) { 178*7c478bd9Sstevel@tonic-gate if (pk->p_is[seq] & (B_COPY | B_MARK)) { 179*7c478bd9Sstevel@tonic-gate dup: 180*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_RR; 181*7c478bd9Sstevel@tonic-gate skip++; 182*7c478bd9Sstevel@tonic-gate goto free; 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate if (x != seq) { 185*7c478bd9Sstevel@tonic-gate p = pk->p_ib[x]; 186*7c478bd9Sstevel@tonic-gate pk->p_ib[x] = pk->p_ib[seq]; 187*7c478bd9Sstevel@tonic-gate pk->p_is[x] = pk->p_is[seq]; 188*7c478bd9Sstevel@tonic-gate pk->p_ib[seq] = p; 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate pk->p_is[seq] = B_MARK; 191*7c478bd9Sstevel@tonic-gate accept++; 192*7c478bd9Sstevel@tonic-gate cc = 0; 193*7c478bd9Sstevel@tonic-gate if (cntl&B_SHORT) { 194*7c478bd9Sstevel@tonic-gate pk->p_is[seq] = B_MARK+B_SHORT; 195*7c478bd9Sstevel@tonic-gate p = pk->p_ib[seq]; 196*7c478bd9Sstevel@tonic-gate cc = (unsigned)*p++ & 0377; 197*7c478bd9Sstevel@tonic-gate if (cc & 0200) { 198*7c478bd9Sstevel@tonic-gate cc &= 0177; 199*7c478bd9Sstevel@tonic-gate cc |= *p << 7; 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate pk->p_isum[seq] = pk->p_rsize - cc; 203*7c478bd9Sstevel@tonic-gate } else { 204*7c478bd9Sstevel@tonic-gate goto dup; 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate } else { 207*7c478bd9Sstevel@tonic-gate bad++; 208*7c478bd9Sstevel@tonic-gate goto free; 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate /* 213*7c478bd9Sstevel@tonic-gate * scan window again turning marked buffers into 214*7c478bd9Sstevel@tonic-gate * COPY buffers and looking for missing sequence 215*7c478bd9Sstevel@tonic-gate * numbers. 216*7c478bd9Sstevel@tonic-gate */ 217*7c478bd9Sstevel@tonic-gate accept = 0; 218*7c478bd9Sstevel@tonic-gate for(x=next[pk->p_pr],t= -1; m & mask[x]; x = next[x]) { 219*7c478bd9Sstevel@tonic-gate if (pk->p_is[x] & B_MARK) 220*7c478bd9Sstevel@tonic-gate pk->p_is[x] |= B_COPY; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate if (pk->p_is[x] & B_COPY) { 223*7c478bd9Sstevel@tonic-gate if (t >= 0) { 224*7c478bd9Sstevel@tonic-gate bp = (char **)pk->p_ib[x]; 225*7c478bd9Sstevel@tonic-gate *bp = (char *)pk->p_ipool; 226*7c478bd9Sstevel@tonic-gate pk->p_ipool = bp; 227*7c478bd9Sstevel@tonic-gate pk->p_is[x] = 0; 228*7c478bd9Sstevel@tonic-gate skip++; 229*7c478bd9Sstevel@tonic-gate } else 230*7c478bd9Sstevel@tonic-gate accept++; 231*7c478bd9Sstevel@tonic-gate } else if (t<0) 232*7c478bd9Sstevel@tonic-gate t = x; 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate if (bad) { 236*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_RJ; 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate if (skip) { 240*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_RR; 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate pk->p_rcount = accept; 244*7c478bd9Sstevel@tonic-gate return(accept); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate int 249*7c478bd9Sstevel@tonic-gate pkread(ibuf, icount) 250*7c478bd9Sstevel@tonic-gate char *ibuf; 251*7c478bd9Sstevel@tonic-gate int icount; 252*7c478bd9Sstevel@tonic-gate { 253*7c478bd9Sstevel@tonic-gate register struct pack *pk; 254*7c478bd9Sstevel@tonic-gate register x; 255*7c478bd9Sstevel@tonic-gate int is,cc,xfr,count; 256*7c478bd9Sstevel@tonic-gate char *cp, **bp; 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate pk = Pk; 259*7c478bd9Sstevel@tonic-gate xfr = 0; 260*7c478bd9Sstevel@tonic-gate count = 0; 261*7c478bd9Sstevel@tonic-gate while (pkaccept()==0) 262*7c478bd9Sstevel@tonic-gate ; 263*7c478bd9Sstevel@tonic-gate Connodata = 0; /* accecpted a packet -- good data */ 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate while (icount) { 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate x = next[pk->p_pr]; 269*7c478bd9Sstevel@tonic-gate is = pk->p_is[x]; 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate if (is & B_COPY) { 272*7c478bd9Sstevel@tonic-gate cc = MIN(pk->p_isum[x], icount); 273*7c478bd9Sstevel@tonic-gate if (cc==0 && xfr) { 274*7c478bd9Sstevel@tonic-gate break; 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate if (is & B_RESID) 277*7c478bd9Sstevel@tonic-gate cp = pk->p_rptr; 278*7c478bd9Sstevel@tonic-gate else { 279*7c478bd9Sstevel@tonic-gate cp = pk->p_ib[x]; 280*7c478bd9Sstevel@tonic-gate if (is & B_SHORT) { 281*7c478bd9Sstevel@tonic-gate if (*cp++ & 0200) 282*7c478bd9Sstevel@tonic-gate cp++; 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate if (cc) 286*7c478bd9Sstevel@tonic-gate memcpy(ibuf, cp, cc); 287*7c478bd9Sstevel@tonic-gate ibuf += cc; 288*7c478bd9Sstevel@tonic-gate icount -= cc; 289*7c478bd9Sstevel@tonic-gate count += cc; 290*7c478bd9Sstevel@tonic-gate xfr++; 291*7c478bd9Sstevel@tonic-gate pk->p_isum[x] -= cc; 292*7c478bd9Sstevel@tonic-gate if (pk->p_isum[x] == 0) { 293*7c478bd9Sstevel@tonic-gate pk->p_pr = x; 294*7c478bd9Sstevel@tonic-gate bp = (char **)pk->p_ib[x]; 295*7c478bd9Sstevel@tonic-gate *bp = (char *)pk->p_ipool; 296*7c478bd9Sstevel@tonic-gate pk->p_ipool = bp; 297*7c478bd9Sstevel@tonic-gate pk->p_is[x] = 0; 298*7c478bd9Sstevel@tonic-gate pk->p_rcount--; 299*7c478bd9Sstevel@tonic-gate pk->p_msg |= M_RR; 300*7c478bd9Sstevel@tonic-gate } else { 301*7c478bd9Sstevel@tonic-gate pk->p_rptr = cp+cc; 302*7c478bd9Sstevel@tonic-gate pk->p_is[x] |= B_RESID; 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate if (cc==0) 305*7c478bd9Sstevel@tonic-gate break; 306*7c478bd9Sstevel@tonic-gate } else 307*7c478bd9Sstevel@tonic-gate break; 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate pkoutput(pk); 310*7c478bd9Sstevel@tonic-gate return(count); 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate /* return number of bytes writtten */ 314*7c478bd9Sstevel@tonic-gate int 315*7c478bd9Sstevel@tonic-gate pkwrite(ibuf, icount) 316*7c478bd9Sstevel@tonic-gate char *ibuf; 317*7c478bd9Sstevel@tonic-gate int icount; 318*7c478bd9Sstevel@tonic-gate { 319*7c478bd9Sstevel@tonic-gate register struct pack *pk; 320*7c478bd9Sstevel@tonic-gate register x; 321*7c478bd9Sstevel@tonic-gate caddr_t cp; 322*7c478bd9Sstevel@tonic-gate int partial; 323*7c478bd9Sstevel@tonic-gate int cc, fc, count; 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate pk = Pk; 326*7c478bd9Sstevel@tonic-gate if (pk->p_state&DOWN || !pk->p_state&LIVE) { 327*7c478bd9Sstevel@tonic-gate return(-1); 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate count = icount; 331*7c478bd9Sstevel@tonic-gate do { 332*7c478bd9Sstevel@tonic-gate while (pk->p_xcount>=pk->p_swindow) { 333*7c478bd9Sstevel@tonic-gate pkoutput(pk); 334*7c478bd9Sstevel@tonic-gate pkgetpack(pk); 335*7c478bd9Sstevel@tonic-gate } 336*7c478bd9Sstevel@tonic-gate x = next[pk->p_pscopy]; 337*7c478bd9Sstevel@tonic-gate while (pk->p_os[x]!=B_NULL) { 338*7c478bd9Sstevel@tonic-gate pkgetpack(pk); 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate pk->p_os[x] = B_MARK; 341*7c478bd9Sstevel@tonic-gate pk->p_pscopy = x; 342*7c478bd9Sstevel@tonic-gate pk->p_xcount++; 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate cp = pk->p_ob[x] = (caddr_t) malloc((unsigned) pk->p_xsize); 345*7c478bd9Sstevel@tonic-gate partial = 0; 346*7c478bd9Sstevel@tonic-gate if ((int)icount < pk->p_xsize) { 347*7c478bd9Sstevel@tonic-gate cc = icount; 348*7c478bd9Sstevel@tonic-gate fc = pk->p_xsize - cc; 349*7c478bd9Sstevel@tonic-gate *cp = fc&0177; 350*7c478bd9Sstevel@tonic-gate if (fc > 127) { 351*7c478bd9Sstevel@tonic-gate *cp++ |= 0200; 352*7c478bd9Sstevel@tonic-gate *cp++ = fc>>7; 353*7c478bd9Sstevel@tonic-gate } else 354*7c478bd9Sstevel@tonic-gate cp++; 355*7c478bd9Sstevel@tonic-gate partial = B_SHORT; 356*7c478bd9Sstevel@tonic-gate } else 357*7c478bd9Sstevel@tonic-gate cc = pk->p_xsize; 358*7c478bd9Sstevel@tonic-gate memcpy(cp, ibuf, cc); 359*7c478bd9Sstevel@tonic-gate ibuf += cc; 360*7c478bd9Sstevel@tonic-gate icount -= cc; 361*7c478bd9Sstevel@tonic-gate pk->p_osum[x] = chksum(pk->p_ob[x], pk->p_xsize); 362*7c478bd9Sstevel@tonic-gate pk->p_os[x] = B_READY+partial; 363*7c478bd9Sstevel@tonic-gate pkoutput(pk); 364*7c478bd9Sstevel@tonic-gate } while (icount); 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate return(count); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate int 370*7c478bd9Sstevel@tonic-gate pksack(pk) 371*7c478bd9Sstevel@tonic-gate register struct pack *pk; 372*7c478bd9Sstevel@tonic-gate { 373*7c478bd9Sstevel@tonic-gate register x, i; 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate i = 0; 376*7c478bd9Sstevel@tonic-gate for(x=pk->p_ps; x!=pk->p_rpr; ) { 377*7c478bd9Sstevel@tonic-gate x = next[x]; 378*7c478bd9Sstevel@tonic-gate if (pk->p_os[x]&B_SENT) { 379*7c478bd9Sstevel@tonic-gate i++; 380*7c478bd9Sstevel@tonic-gate Connodata = 0; 381*7c478bd9Sstevel@tonic-gate pk->p_os[x] = B_NULL; 382*7c478bd9Sstevel@tonic-gate pk->p_state &= ~WAITO; 383*7c478bd9Sstevel@tonic-gate pk->p_xcount--; 384*7c478bd9Sstevel@tonic-gate free((char *) pk->p_ob[x]); 385*7c478bd9Sstevel@tonic-gate pk->p_ps = x; 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate return(i); 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate void 393*7c478bd9Sstevel@tonic-gate pkoutput(pk) 394*7c478bd9Sstevel@tonic-gate register struct pack *pk; 395*7c478bd9Sstevel@tonic-gate { 396*7c478bd9Sstevel@tonic-gate register x; 397*7c478bd9Sstevel@tonic-gate char bstate; 398*7c478bd9Sstevel@tonic-gate int i; 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate if (pk->p_obusy++) { 401*7c478bd9Sstevel@tonic-gate pk->p_obusy--; 402*7c478bd9Sstevel@tonic-gate return; 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate /* 407*7c478bd9Sstevel@tonic-gate * find seq number and buffer state 408*7c478bd9Sstevel@tonic-gate * of next output packet 409*7c478bd9Sstevel@tonic-gate */ 410*7c478bd9Sstevel@tonic-gate if (pk->p_state&RXMIT) 411*7c478bd9Sstevel@tonic-gate pk->p_nxtps = next[pk->p_rpr]; 412*7c478bd9Sstevel@tonic-gate x = pk->p_nxtps; 413*7c478bd9Sstevel@tonic-gate bstate = pk->p_os[x]; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate /* 417*7c478bd9Sstevel@tonic-gate * Send control packet if indicated 418*7c478bd9Sstevel@tonic-gate */ 419*7c478bd9Sstevel@tonic-gate if (pk->p_msg) { 420*7c478bd9Sstevel@tonic-gate if (pk->p_msg & ~M_RR || !(bstate&B_READY) ) { 421*7c478bd9Sstevel@tonic-gate x = pk->p_msg; 422*7c478bd9Sstevel@tonic-gate for(i=0; i<8; i++) 423*7c478bd9Sstevel@tonic-gate if (x&1) 424*7c478bd9Sstevel@tonic-gate break; 425*7c478bd9Sstevel@tonic-gate else 426*7c478bd9Sstevel@tonic-gate x >>= 1; 427*7c478bd9Sstevel@tonic-gate x = i; 428*7c478bd9Sstevel@tonic-gate x <<= 3; 429*7c478bd9Sstevel@tonic-gate switch(i) { 430*7c478bd9Sstevel@tonic-gate case CLOSE: 431*7c478bd9Sstevel@tonic-gate break; 432*7c478bd9Sstevel@tonic-gate case RJ: 433*7c478bd9Sstevel@tonic-gate case RR: 434*7c478bd9Sstevel@tonic-gate x += pk->p_pr; 435*7c478bd9Sstevel@tonic-gate break; 436*7c478bd9Sstevel@tonic-gate case INITB: 437*7c478bd9Sstevel@tonic-gate x += pksize(pk->p_rsize); 438*7c478bd9Sstevel@tonic-gate break; 439*7c478bd9Sstevel@tonic-gate case INITC: 440*7c478bd9Sstevel@tonic-gate x += pk->p_rwindow; 441*7c478bd9Sstevel@tonic-gate break; 442*7c478bd9Sstevel@tonic-gate case INITA: 443*7c478bd9Sstevel@tonic-gate x += pk->p_rwindow; 444*7c478bd9Sstevel@tonic-gate break; 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate pk->p_msg &= ~mask[i]; 448*7c478bd9Sstevel@tonic-gate pkxstart(pk, x, -1); 449*7c478bd9Sstevel@tonic-gate goto out; 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate 454*7c478bd9Sstevel@tonic-gate /* 455*7c478bd9Sstevel@tonic-gate * Don't send data packets if line is marked dead. 456*7c478bd9Sstevel@tonic-gate */ 457*7c478bd9Sstevel@tonic-gate if (pk->p_state&DOWN) { 458*7c478bd9Sstevel@tonic-gate goto out; 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate /* 462*7c478bd9Sstevel@tonic-gate * Start transmission (or retransmission) of data packets. 463*7c478bd9Sstevel@tonic-gate */ 464*7c478bd9Sstevel@tonic-gate if (bstate & (B_READY|B_SENT)) { 465*7c478bd9Sstevel@tonic-gate char seq; 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate bstate |= B_SENT; 468*7c478bd9Sstevel@tonic-gate seq = x; 469*7c478bd9Sstevel@tonic-gate pk->p_nxtps = next[x]; 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate x = 0200+pk->p_pr+(seq<<3); 472*7c478bd9Sstevel@tonic-gate if (bstate & B_SHORT) 473*7c478bd9Sstevel@tonic-gate x |= 0100; 474*7c478bd9Sstevel@tonic-gate pkxstart(pk, x, seq); 475*7c478bd9Sstevel@tonic-gate pk->p_os[seq] = bstate; 476*7c478bd9Sstevel@tonic-gate pk->p_state &= ~RXMIT; 477*7c478bd9Sstevel@tonic-gate pk->p_nout++; 478*7c478bd9Sstevel@tonic-gate goto out; 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate /* 482*7c478bd9Sstevel@tonic-gate * enable timeout if there's nothing to send 483*7c478bd9Sstevel@tonic-gate * and transmission buffers are languishing 484*7c478bd9Sstevel@tonic-gate */ 485*7c478bd9Sstevel@tonic-gate if (pk->p_xcount) { 486*7c478bd9Sstevel@tonic-gate pk->p_timer = 2; 487*7c478bd9Sstevel@tonic-gate pk->p_state |= WAITO; 488*7c478bd9Sstevel@tonic-gate } else 489*7c478bd9Sstevel@tonic-gate pk->p_state &= ~WAITO; 490*7c478bd9Sstevel@tonic-gate out: 491*7c478bd9Sstevel@tonic-gate pk->p_obusy = 0; 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate /* 495*7c478bd9Sstevel@tonic-gate * shut down line by ignoring new input 496*7c478bd9Sstevel@tonic-gate * letting output drain 497*7c478bd9Sstevel@tonic-gate * releasing space 498*7c478bd9Sstevel@tonic-gate */ 499*7c478bd9Sstevel@tonic-gate void 500*7c478bd9Sstevel@tonic-gate pkclose() 501*7c478bd9Sstevel@tonic-gate { 502*7c478bd9Sstevel@tonic-gate register struct pack *pk; 503*7c478bd9Sstevel@tonic-gate register i; 504*7c478bd9Sstevel@tonic-gate int rcheck; 505*7c478bd9Sstevel@tonic-gate char **bp; 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate pk = Pk; 508*7c478bd9Sstevel@tonic-gate pk->p_state |= DRAINO; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate /* 511*7c478bd9Sstevel@tonic-gate * try to flush output 512*7c478bd9Sstevel@tonic-gate */ 513*7c478bd9Sstevel@tonic-gate i = 0; 514*7c478bd9Sstevel@tonic-gate pk->p_timer = 2; 515*7c478bd9Sstevel@tonic-gate while (pk->p_xcount && pk->p_state&LIVE) { 516*7c478bd9Sstevel@tonic-gate if (pk->p_state&(RCLOSE+DOWN) || ++i > 2) 517*7c478bd9Sstevel@tonic-gate break; 518*7c478bd9Sstevel@tonic-gate pkoutput(pk); 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate pk->p_timer = 0; 521*7c478bd9Sstevel@tonic-gate pk->p_state |= DOWN; 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate /* 524*7c478bd9Sstevel@tonic-gate * try to exchange CLOSE messages 525*7c478bd9Sstevel@tonic-gate */ 526*7c478bd9Sstevel@tonic-gate i = 0; 527*7c478bd9Sstevel@tonic-gate while ((pk->p_state&RCLOSE)==0 && i<2) { 528*7c478bd9Sstevel@tonic-gate pk->p_msg = M_CLOSE; 529*7c478bd9Sstevel@tonic-gate pk->p_timer = 2; 530*7c478bd9Sstevel@tonic-gate pkoutput(pk); 531*7c478bd9Sstevel@tonic-gate i++; 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* 535*7c478bd9Sstevel@tonic-gate * free space 536*7c478bd9Sstevel@tonic-gate */ 537*7c478bd9Sstevel@tonic-gate rcheck = 0; 538*7c478bd9Sstevel@tonic-gate for (i=0;i<8;i++) { 539*7c478bd9Sstevel@tonic-gate if (pk->p_os[i]!=B_NULL) { 540*7c478bd9Sstevel@tonic-gate free((char *) pk->p_ob[i]); 541*7c478bd9Sstevel@tonic-gate pk->p_xcount--; 542*7c478bd9Sstevel@tonic-gate } 543*7c478bd9Sstevel@tonic-gate if (pk->p_is[i]!=B_NULL) { 544*7c478bd9Sstevel@tonic-gate free((char *) pk->p_ib[i]); 545*7c478bd9Sstevel@tonic-gate rcheck++; 546*7c478bd9Sstevel@tonic-gate } 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate while (pk->p_ipool != NULL) { 549*7c478bd9Sstevel@tonic-gate bp = pk->p_ipool; 550*7c478bd9Sstevel@tonic-gate pk->p_ipool = (char **)*bp; 551*7c478bd9Sstevel@tonic-gate rcheck++; 552*7c478bd9Sstevel@tonic-gate free((char *) bp); 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate if (rcheck != pk->p_rwindow) { 555*7c478bd9Sstevel@tonic-gate logent("PK0", "pkclose rcheck != p_rwindow"); 556*7c478bd9Sstevel@tonic-gate } 557*7c478bd9Sstevel@tonic-gate free((char *) pk); 558*7c478bd9Sstevel@tonic-gate } 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate void 562*7c478bd9Sstevel@tonic-gate pkreset(pk) 563*7c478bd9Sstevel@tonic-gate register struct pack *pk; 564*7c478bd9Sstevel@tonic-gate { 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate pk->p_ps = pk->p_pr = pk->p_rpr = 0; 567*7c478bd9Sstevel@tonic-gate pk->p_nxtps = 1; 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate static int 571*7c478bd9Sstevel@tonic-gate chksum(s,n) 572*7c478bd9Sstevel@tonic-gate register char *s; 573*7c478bd9Sstevel@tonic-gate register n; 574*7c478bd9Sstevel@tonic-gate { 575*7c478bd9Sstevel@tonic-gate register short sum; 576*7c478bd9Sstevel@tonic-gate register unsigned short t; 577*7c478bd9Sstevel@tonic-gate register short x; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate sum = -1; 580*7c478bd9Sstevel@tonic-gate x = 0; 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate do { 583*7c478bd9Sstevel@tonic-gate if (sum<0) { 584*7c478bd9Sstevel@tonic-gate sum <<= 1; 585*7c478bd9Sstevel@tonic-gate sum++; 586*7c478bd9Sstevel@tonic-gate } else 587*7c478bd9Sstevel@tonic-gate sum <<= 1; 588*7c478bd9Sstevel@tonic-gate t = sum; 589*7c478bd9Sstevel@tonic-gate sum += (unsigned)*s++ & 0377; 590*7c478bd9Sstevel@tonic-gate x += sum^n; 591*7c478bd9Sstevel@tonic-gate if ((unsigned short)sum <= t) { 592*7c478bd9Sstevel@tonic-gate sum ^= x; 593*7c478bd9Sstevel@tonic-gate } 594*7c478bd9Sstevel@tonic-gate } while (--n > 0); 595*7c478bd9Sstevel@tonic-gate 596*7c478bd9Sstevel@tonic-gate return(sum); 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate static int 600*7c478bd9Sstevel@tonic-gate pksize(n) 601*7c478bd9Sstevel@tonic-gate register n; 602*7c478bd9Sstevel@tonic-gate { 603*7c478bd9Sstevel@tonic-gate register k; 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate n >>= 5; 606*7c478bd9Sstevel@tonic-gate for(k=0; n >>= 1; k++); 607*7c478bd9Sstevel@tonic-gate return(k); 608*7c478bd9Sstevel@tonic-gate } 609